PROCEDURE ,010009 ;+ ; 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 the action routines for most of ; the Runoff commands. ; ; R4 = Address of number conversion routine. ; R5 = Address of flag word F.1. ; ; Written: 01-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: 26-May-80, -1.0.1-, Jon Berntsen .IF DF A$$RAP ; ; Modified: 26-Aug-80, -1.0.2-, John D. Leonard for .SETSS ; Fixed Old Figure Command to blank at top of page. ; ; Modified: 30-Sep-80, -1.0.3-, John D. Leonard ; Fixed BLANK command - was defaulting to skipping two lines. ; ; Modified: 02-Sep-80, -1.0.4-, John D. Leonard ; Commands to accept spacing count in 1/8 line increments ; ; Modified: 07-Oct-80, -1.0.5-, John D. Leonard ; Modified .NPL command, ; Added .NNPL (no number page lower), ; Added .TM (Top Margin), ; Added .OP (Over print), ; Added .OPJ (Over print right justified) ; Added .OB (Over Bar) ; Added .EQ (EQuation mode) ; Added .EEQ (End EQuation mode) ; ; MODIFIED: 05-NOV-80, -1.0.6-, JOHN D. LEONARD ; ADDED .SETS (SET STRING) COMMAND ; ; Modified: 22-Dec-80, -1.0.7-, John D. Leonard ; Put test page into footnote command so an attempt to footnote at ; at bottom of page with insufficient page length forces footnote to ; next page. ; ; Modified: 06-Jan-81, -1.0.8-, John D. Leonard ; Changed .CENTER command parameters for clarification. Now specify ; .CENTER lm,rm; text to center between the given left/right margins. ; Straightened out minor problems with .RM and added checking to ; .LM and .RM against permanent settings. ; Removed the second parameter to the .PS command, so only the page length ; can be specified. .PRM and .PLM should be used for margin setting. ; Too confusing. ; Added 2nd parameter to .FN command to allow specification of footnote ; terminator character. ; Removed multiplication of footnote space by spacing. ; Changed PAGE command so that it calls BPAGE. Problem with page pending ; mechanism and footnotes. If a .NF command or other mode command followed ; a .PG, it would change the setting before footnotes were printed. ; Relative setting in .PS command does not properly modify NLPG to ; account for the relative setting. ; This problem only occurs when the page size is changed and the page ; has footnotes. Footnote checking modifies NLPG ! ; ; Modified: 03-Nov-81, -1.0.9-, John D. Leonard ; Changed .PARAGRAPH and .LIST spacing arguments to 1/8 line format. ; Also on autoparagraph command. .ENDC ;- .SBTTL Runoff definitions(external) .GLOBL ALLOC ; Memory allocator .GLOBL BPAGE ; Break current page .GLOBL CAS ; .GLOBL CBNSP ; .GLOBL CCIN ; Get character from buffer .GLOBL CMADR ; Command address .GLOBL DATEBF ; Date buffer .GLOBL DATECT ; Count of characters in date buffer .GLOBL DATTBF ; TOC date buffer .GLOBL DATTCT ; TOC count of characters in date buffer .GLOBL EBSIZ ; Change bars offset .GLOBL ELCMD ; .GLOBL EOF ; End-of-File character .GLOBL FILLF ; .GLOBL FOOTC ; .GLOBL FOOTLH ; Footnote list head .GLOBL FOOTP1 ; Footnote header area .GLOBL GCIN ; Get character from input file .GLOBL GCSCH ; Saved character buffer .GLOBL ILCM ; Common error point for illegal command .GLOBL ILMRG ; Initial left margin .GLOBL INDCT ; Indentation count .GLOBL INLPG ; Initial lines/page .GLOBL IPARIN ; .GLOBL IPARPT ; .GLOBL JUSTF ; .GLOBL LF ; Line feed .GLOBL LIBUF ; Line input buffer header .GLOBL LINEC ; .GLOBL LITCM ; .GLOBL LITFG ; .GLOBL LITSV ; .GLOBL LMARG ; Current left margin .GLOBL METBEG ; .GLOBL METEND ; .GLOBL NEWFIL ; .GLOBL NLPG ; Number of lines per page .GLOBL NSPAC ; Output spaces to output file .GLOBL NSPCH ; .GLOBL NSPNG ; .GLOBL NTABS ; .GLOBL PAGENO ; .GLOBL PARIND ; Paragraph indentation count .GLOBL PARPT ; .GLOBL PARSP ; Paragraph spacing .GLOBL PJUSTF ; .GLOBL PLMARG ; Permanent left margin .GLOBL PNLPG ; Permanent number of lines/page .GLOBL PRMARG ; .GLOBL PRMRG ; .GLOBL PSHFIL ; .GLOBL PSTRPA ; Insert ASCIZ string in buffer .GLOBL RIGSHI ; Right Shift value .SBTTL Runoff definitions(external), continued .GLOBL RMARG ; Current right margin .GLOBL SEMI ; Semicolon .GLOBL SKIPN ; Skip N lines to the output file .GLOBL SKIPS ; Skip lines according to spacing .GLOBL SPC ; Blank .GLOBL SPCNG ; .GLOBL SPECF ; .GLOBL STTLBF ; Subtitle buffer header .GLOBL TAB ; Tab .GLOBL TABTAB ; .GLOBL TABTL ; .GLOBL TPNLPG ; TOC permanent lines/page .GLOBL TTLBUF ; Title buffer header .GLOBL ULBSET ; .GLOBL UPCSW ; .GLOBL WCAS ; .GLOBL WCI ; Write character in buffer .GLOBL WCIFTN ; Write character in footnote buffer .GLOBL WLNIN1 ; .GLOBL $AUTSW ; Autoparagraph switch .GLOBL $CBON ; Change bars on switch .GLOBL $CFLSW ; .GLOBL $DATE ; Date switch .GLOBL $DATET ; TOC date switch .GLOBL $FRCND ; Force to logical end of command .GLOBL $HDRSW ; Header switch .GLOBL $HFLSW ; .GLOBL $HPHSW ; Hyphenation switch .GLOBL $INSW ; Input file switches .GLOBL $NUMLW ; Number pages low switch .GLOBL $NUMSW ; .GLOBL $PERSW ; .IF NDF A$$RAP .GLOBL $PGPSW ; .ENDC .SBTTL Runoff definitions(internal) .GLOBL AUTOP ; Autoparagraph .GLOBL BGBAR ; Begin Change bars .GLOBL BREAK ; Break command .GLOBL CENTER ; Center command .GLOBL CHANG ; Change metacharacter. .GLOBL CPAGE ; Page command .GLOBL PAGEC .GLOBL DATE ; Date command .GLOBL DSAFL ; Disable all flags .GLOBL DSCBR ; Disable change bars .GLOBL DSCFL ; Disable flags capitalize .GLOBL DSHFL ; Disable flags hyphenate .GLOBL ELTRL ; End literal command .GLOBL ENBAR ; End change bars .GLOBL ENCBR ; Enable change bars .IF DF A$$RAP .GLOBL EQON ; Enable Equation mode .GLOBL EQOFF ; Disable Equation mode .ENDC .GLOBL FIGUR ; Figure command .GLOBL FILLN ; Fill command .GLOBL FILOF ; Nofill command .GLOBL FOOTN ; Footnote command .GLOBL FTITL ; First title command .GLOBL HYPHN ; Enable hyphenation .GLOBL INDENT ; Indent command .GLOBL INDIRC ; Include command .GLOBL JUSOF ; Justify command .GLOBL JUSTN ; Nojustify command .GLOBL LINSKP ; Blank command .GLOBL LITRL ; Literal command .GLOBL LITSV ; .GLOBL LMARG ; .GLOBL LSTTP ; .GLOBL LWCAS ; LC command .GLOBL NAUTO ; Disable autoparagraph .GLOBL NHYPH ; Disable hyphenation .GLOBL NPERS ; .GLOBL NUMLW ; .IF DF A$$RAP .GLOBL NUMLWO ; Disable Number Page Lower .ENDC .GLOBL NUMOF ; Nonumber command .GLOBL NUMON ; Number command .IF DF A$$RAP .GLOBL OVERP ; Overprint line .GLOBL OVERPJ ; Overprint line right justified .GLOBL OVERB ; Overprint overbar .ENDC .GLOBL PARAG ; Paragraph command .GLOBL PARTP ; .GLOBL PERSP ; .GLOBL SELM ; PLM command .GLOBL SERM ; PRM command .GLOBL SETBF ; .GLOBL SETLM ; LM command .GLOBL SETPG ; .GLOBL SETRM ; RM command .GLOBL SETSTL ; Subtitle command .GLOBL SETTAB ; Tabstop command .GLOBL SETTL ; Title command .IF DF A$$RAP .GLOBL SETTM ; Set Top Margin .ENDC .GLOBL SHFUC ; Shift to upper case .GLOBL SKIPL ; Skip command .GLOBL SSP ; Spacing command .IF DF A$$RAP .GLOBL SUBSTD ; Set string delimited .GLOBL SUBST ; Set string .GLOBL SETSS ; Set sub/supperscript vertical increment .ENDC .GLOBL STAND ; Standard command .GLOBL SWPFIL ; Swap output files .GLOBL TESTP ; Test page command .GLOBL TSTPG ; .GLOBL UPCAS ; UC command .SBTTL ENCBR -- ENABLE CHANGE BARS CODE RNCMD .sbttl Enable/Disable change bar commands(Also on and off) ENCBR:: CLR $CBON ; Clear on MOV #CBNSP,EBSIZ ; Number of chars to move to right RETURN ; .SBTTL DSCBR -- Disable change bars DSCBR:: CLR EBSIZ ; Set offset back to zero CLR $CBON ; Turn off change bar RETURN .sbttl BGBAR -- Begin change bars BGBAR:: MOV #CBBIT,$CBON ; Turn on change bars RETURN .sbttl ENBAR -- End change bars ENBAR:: MOV #CBFBT,$CBON ; Turn off change bars RETURN .SBTTL AUTOP -- Enable AUTOPARAGRAPH AUTOP:: MOV SP,$AUTSW ; set autoparagraph mode CALL (R4) ; optional identing argument MOV PARIND,R3 ; no. use old value CMP R3,RMARG ; reasonable value? BLE 20$ ; LE - then ok 10$: JMP ILCM ; Else illegal command 20$: MOV R3,INDCT ; set paragraph indent MOV R3,PARIND ; store para indent value .if df A$$RAP MOV SP,$MFAC ; Set for 1/8 line type argument .iftf CALL (R4) ; get paragraph spacing MOV PARSP,R3 ; default to normal spacing .ift CLR $MFAC ; Clear the condition .endc CMP R3,#<5*DIVPL> ; legal value? BHI 10$ ; if HI no MOV R3,PARSP ; set new paragraph spacing CALL (R4) ; get test page count MOV #IPARPT,R3 ; default page test number CMP R3,PNLPG ; value within reason? BHI 10$ ; if HI no MOV R3,PARPT ; set new paragraph page test count RETURN ; .SBTTL NAUTO -- Disable AUTOPARAGRAPH NAUTO:: CLR $AUTSW ; clear autoparagraph mode RETURN ; .SBTTL DSAFL -- DISABLE ALL FLAGS DSAFL:: CLR $CFLSW ; clear flags capitalize CLR $HFLSW ; clear flags hyphenate RETURN ; .SBTTL ENCFL -- Enable Flags Capitalize .ENABL LSB ENCFL:: MOV SP,$CFLSW ; set word capitalize enable 10$: CLR WCAS ; clear case conversion value RETURN ; .SBTTL DSCFL -- Disable Flags Capitalize DSCFL:: CLR $CFLSW ; clear word capitalize enable BR 10$ ; .DSABL LSB .sbttl ENHFL -- Enable Flags Hyphenate ENHFL:: MOV SP,$HFLSW ; set hyphenate enable RETURN ; .sbttl DSHFL -- Disable Flags Hyphenate DSHFL:: CLR $HFLSW ; clear hyphenate enable RETURN ; .sbttl HYPHN -- Enable Hyphenation HYPHN:: MOV SP,$HPHSW ; set hyphenation active RETURN ; .sbttl NHYPN -- Disable hyphenation NHYPH:: CLR $HPHSW ; clear hyphenation active RETURN ; .SBTTL INDENT -- INDENT COMMAND INDENT::CALL (R4) ; read signed decimal number MOV PARIND,R3 ; none. use current value CMP R3,RMARG ; legitimate value? BLE 10$ JMP ILCM ; no. complain 10$: MOV R3,INDCT ; yes. store argument .sbttl BREAK -- BREAK COMMAND BREAK:: RETURN ; Return, flags will do the rest .SBTTL LWRCAS -- Set mode to lower case .ENABL LSB LWCAS:: MOV #40,R1 ; set for lower case BITEQ #UPCSW,$INSW,10$ ; don't force all upper case? .SBTTL UPCAS -- Set mode to upper case UPCAS:: CLR R1 ; set for upper case 10$: MOV R1,CAS ; store RETURN ; .DSABL LSB .sbttl PAGE NUMBER SELECTION COMMANDS .sbttl NUMON -- Turn on and set page numbering NUMON:: CALL (R4) ; number pages. any particular number? MOV PAGENO,R3 ; no. leave same as before MOV R3,PAGENO ; store page number MOV SP,$NUMSW ; turn on flag to cause numbering RETURN ; .sbttl NUMOF -- Turn off page numbering NUMOF:: CLR $NUMSW ; turn off numbering. RETURN ; .sbttl NUMLW -- NUMBER PAGES LOW NUMLW:: .IF NDF A$$RAP CLR PAGENO ; clear page number .ENDC CALL (R4) ; get page number if any MOV PAGENO,R3 ; set default MOV R3,PAGENO ; set new page number .IF NDF A$$RAP MOV #1,$NUMLW ; set flag .IFF TSTNE $NUMLW,10$ ; If already on don't reset page length MOV #NLFTR,$NUMLW ; Set to # of lines in footer SUB $NUMLW,NLPG ; Adjust # of lines per page 10$: ; .ENDC RETURN .IF DF A$$RAP .SBTTL NUMLWO - Turn off number pages low NUMLWO:: ADD $NUMLW,NLPG ; Increase length of page CLR $NUMLW ; Clear flag RETURN .ENDC .sbttl CPAGE -- PAGE COMMAND CPAGE:: MOV LINEC,R2 ; Get current line count on page SUB #DIVPL,R2 ; minus the header size CMP $HDRSW,R2 ; In header area ? BGE 20$ ; GE - then ignore doing page 10$: .IF NDF A$$RAP MOV SP,$PGPSW ; set page pending flag .IFF CALL PAGEC ; do the page .ENDC 20$: RETURN ; .sbttl MARGIN SELECTION COMMANDS .sbttl SETRM -- Set right margin .ENABL LSB SETRM:: MOV RMARG,R3 ; get current right margin CALL (R4) ; get relative argument MOV PRMRG,R3 ; if none, initialize CMP R3,LMARG ; must be right of left margin BLE 110$ ; report error CMP R3,PRMARG ; Must be less than or equal to permanent margin BLE 10$ ; OK MOV PRMARG,R3 ; Set it to current right margin then 10$: MOV R3,RMARG ; and set the margin RETURN ; .sbttl SETLM -- Set left margin SETLM:: MOV LMARG,R3 ; get current left margin CALL (R4) ; get relative argument .IF NDF A$$RAP MOV #ILMRG,R3 ; if none, initialize .IFF MOV ILMRG,R3 ; if none , initialize .ENDC CMP R3,RMARG ; must be less than right margin? BGE 110$ ; if GE no CMP R3,PLMARG ; Must be greater than or equal to permanent left BGE 20$ ; OK MOV PLMARG,R3 ; else set to permanent left margin 20$: MOV R3,LMARG ; OK, save as left margin RETURN ; .sbttl PERMANENT MARGIN SELECTION COMMANDS .sbttl SERM -- Set permanent right margin SERM:: MOV PRMARG,R3 ; get current right margin CALL (R4) ; get relative argument MOV PRMRG,R3 ; if none, initialize CMP R3,LMARG ; must be right of left margin BGT 120$ ; if GT ok 110$: JMP ILCM ; illegal command 120$: MOV R3,PRMARG ; set permanent right margin .IF DF A$$RAP MOV R3,RMARG ; Set right margin MOV R3,PRMRG ; ? .ENDC RETURN .sbttl SELM -- Set permanent left margin SELM:: MOV PLMARG,R3 ; get current left margin CALL (R4) ; get relative argument .IF NDF A$$RAP MOV #ILMRG,R3 ; if none, initialize .IFF MOV ILMRG,R3 ; If none, initialize .ENDC CMP R3,RMARG ; must be less than right margin? BGE 110$ ; if GE no MOV R3,LMARG ; ok save as left margin MOV R3,PLMARG ; save as permanent left margin RETURN ; .IF DF A$$RAP .sbttl SETTM -- SET Top margin command SETTM:: CALL (R4) ; Get argument MOV #ITMRG,R3 ; Default to initial setting if no arg. MOV R3,TMARG ; save it in Top Margin RETURN .ENDC .DSABL LSB .ENABL LSB .sbttl STAND -- STANDARD COMMAND STAND:: MOV #SPCNG,NSPNG ; set standard spacing .IF NDF A$$RAP MOV #ILMRG, LMARG ; initialize left margin .IFF MOV ILMRG,LMARG ; iniialize left margin .ENDC MOV #IPARIN,PARIND ; set initial paragraph indent MOV #INLPG,R3 ; set initial page length parameter BIS #FILLF!JUSTF!PJUSTF,(R5) ; set to fill and justify CALL 15$ ; finish in common code CALL SERM ; Set permanent right margin RETURN .sbttl SETPG -- PAGE SIZE COMMAND SETPG:: MOV PNLPG,R3 ; get current page length .IF DF A$$RAP MOV SP,$MFAC ; Return in # of 1/8 increments .ENDC CALL (R4) ; get relative argument MOV PNLPG,R3 ; default to current length .IF DF A$$RAP CLR $MFAC ; Clear the switch .ENDC CMP PNLPG,R3 ; identical ? BEQ 17$ ; EQ - then don't bother setting it CMP R3,#<6*DIVPL> ; long enough to be reasonable for heading BGT 15$ ; if LE error 10$: JMP ILCM ; Report error 15$: .IF NDF R$$OCK ASL R3 ; multiply by two .ENDC ; R$$OCK SUB PNLPG,R3 ; Find difference from old setting ADD R3,NLPG ; add to length of this page ADD R3,PNLPG ; and permanent page length .IF NDF A$$RAP ASR R3 .IFF ASH #DIV8,R3 ; divide page length by 8 and save .ENDC ADD R3,TPNLPG ; divide page length by 2 and save 17$: .IF NDF A$$RAP CALL SETRM ; set right margin MOV R3,PRMRG ; set new permanent margin 20$: MOV R3,RMARG MOV R3,PRMARG ; set new permanent right margin .ENDC RETURN ; .sbttl PARAG -- PARAGRAPH COMMAND PARAG:: CALL (R4) ; optional indenting argument MOV PARIND,R3 ; no. use old value CMP R3,RMARG ; reasonable value? BGT 10$ ; if GT no MOV R3,INDCT ; set paragraph indent MOV R3,PARIND ; store para indent value .if df A$$RAP MOV SP,$MFAC ; Set for 1/8 line argument .iftf CALL (R4) ; get paragraph spacing MOV PARSP,R3 ; default to normal spacing .ift CLR $MFAC ; Reset 1/8 line indicator .endc CMP R3,#<5*DIVPL> ; legal value, max 5 lines BHI 10$ ; if HI no MOV R3,PARSP ; set new paragraph spacing CALL (R4) ; get test page count "spaces" MOV #IPARPT,R3 ; default page test number CMP R3,PNLPG ; value within reason? BHI 10$ ; if HI no MOV R3,PARPT ; set new paragraph page test count PARTP:: MOV PARPT,R3 ; get page test count .if ndf A$$RAP ADD PARSP,R3 ; add # of lines between para. .iftf MOV NSPNG,R0 ; .IF NDF R$$EIS ; If no EIS, use $MUL MOV R3,R1 ; Get into R1 for $MUL CALL $MUL ; get total number of half lines .IFF ; If EIS, just use MUL MUL R3,R0 ; Get total number of line divisions .ENDC ;R$$EIS MOV R1,R3 ; .iff ADD PARSP,R3 ; Plus spacing between paragraphs .endc CALL TESTP ; test if room on page 30$: MOV PARSP,R1 ; get current paragraph spacing LSTTP:: BEQ 40$ ; if EQ no spacing .if ndf A$$RAP MOV NSPNG,R0 ; get lines per line .IF NDF R$$EIS ; If no EIS, use $MUL CALL $MUL ; calculate actual number of lines to skip .IFF ; If EIS, use MUL MUL R1,R0 ; Calculate actual number of lines to skip .ENDC ;R$$EIS .endc CMP $HDRSW,LINEC ; already in heading area? BGE 40$ ; if GE yes MOV R1,R2 ; set line skip count CALL SKIPN ; skip lines 40$: RETURN ; .DSABL LSB .sbttl TSTPG -- TEST PAGE COMMAND ; TSTPG -- Entry point for TEST PAGE command ; TESTP0 __ Internal routine - testpage with R3 multiplied by spacing ; TESTP -- Internal routine - testpage with R3 number of 1/8 lines to test .ENABL LSB TSTPG:: CALL (R4) ; get argument of test JMP ILCM ; must be one CMP R3,PNLPG ; value within reason? BHI 10$ ; if HI no TESTP0::MOV NSPNG,R0 .IF NDF R$$EIS ; If no EIS, use $MUL MOV R3,R1 ; Get into R1 for $MUL CALL $MUL .IFF ; If EIS, use MUL MUL R3,R0 .ENDC ;R$$EIS MOV R1,R3 TESTP:: ADD LINEC,R3 ; add on current line position CMP R3,NLPG ; compare to length w/o footnotes BLE 20$ JMP BPAGE ; test shows near end. break page. .sbttl SSP -- SPACING COMMAND SSP:: .IF DF A$$RAP MOV SP,$MFAC ; Get spacing in 1/8 line increments .ENDC CALL (R4) ; get argument of spacing command 10$: JMP ILCM ; must be one .IF DF A$$RAP CLR $MFAC ; Clear the flag .ENDC CMP R3,#<5*DIVPL> ; must be in range 1 to 5 lines BHI 10$ .IF NDF A$$RAP CMP R3,#1. BHI 15$ ; illegal value? .IFF TST R3 ; Greater or equal to zero is ok BGE 15$ ; .sp 0 is overprint mode .ENDC MOV #DIVPL,R3 15$: .IF NDF R$$OCK ASL R3 ; Make in terms of half lines .ENDC ; R$$OCK MOV R3,NSPNG ; ok. store as normal spacing 20$: RETURN ; .DSABL LSB .IF DF A$$RAP .sbttl SETSS - SET SUB/SUPERSCRIPT MOVEMENT .ENABL LSB SETSS:: MOV SP,$MFAC ; indicate increments of 1/8 line CALL (R4) ; get argument in # of 1/8 line movements MOV #0,R3 ; no arg, default to 4/8 (Half line) CLR $MFAC ; Clear the flag CMP R3,#3. ; must be in range 1/8 to 3/8 BHI 10$ CMP R3,#0. BHI 15$ 10$: CLR R3 15$: MOV R3,SSINC ; okay, store as new sub/super vertical inc. RETURN .DSABL LSB .ENDC .sbttl Title/subtitle commands .sbttl SETSTL -- SUBTITLE COMMAND .ENABL LSB SETSTL::MOV #STTLBF,R5 ; set for subtitle buffer CLRB $LINE2 ; Clear alternate subtitle BR 10$ ; .sbttl FTITL -- FIRST TITLE COMMAND FTITL:: CLRB $HDSSW ; enable header on first page .sbttl SETTL -- TITLE COMMAND SETTL:: MOV #TTLBUF,R5 ; set for title buffer CALL SHFUC ; shift to upper case for title CLRB $LINE1 ; Reset alternate title line 10$: MOV BF.ADR(R5),BF.PTR(R5) ; initialize descriptor CLR BF.LEN(R5) ; Reset length SETBF:: CALL $FRCND ; force to logical end of command 20$: CALL GCIN ; read a character from title or subtitle CMPEQ #CR,R1,30$ ; carriage return? MOV R5,R4 ; point to buffer pointer CALL WCI ; write character in buffer BR 20$ ; 30$: CALL ULBSET ; reset underline buffer .IF DF A$$RAP CALL OBBSET ; reset obverbar buffer .ENDC RETURN ; Set up alternate title/subtitle lines ; ; Format: ; ; .LINE n; text ; ; n is 1 or 2 and specifies the title or subtitle line ; text is the text to replace the title or subtitle. ; STPGTP:: CALL (R4) ; Get line # 2$: JMP ILCM ; Invalid if not specified CLRB $HDSSW ; Enable header on first page CMP R3,#2 ; Can only be 1 or 2 BHI 2$ ; HI - then error BLO 40$ ; LO - then check lower bound MOV #STTLBF,R5 ; Point to buffer to use COMB $LINE2 ; Indicate to use this BR 10$ ; And get line of text 40$: CMP R3,#1 ; Is it within range ? BNE 2$ ; NE - then error COMB $LINE1 ; Indicate to use this MOV #TTLBUF,R5 ; Point to the buffer BR 10$ ; And go get the buffer .DSABL LSB .sbttl LINE SKIPPING COMMANDS .sbttl SKIPL -- Skip command .ENABL LSB .IF NDF A$$RAP SKIPL:: MOV NSPNG,-(SP) ; skip command. n current lines .IFF SKIPL:: CALL (R4) ; skip command. n current lines MOV #1,R3 ; Default to 1 line MOV NSPNG,R0 ; To multilpy by line spacing .ENDC BR 10$ .SBTTL LINSKP -- Blank command .IF NDF A$$RAP LINSKP::MOV #DIVPL,-(SP) ; blank command. n real lines 10$: CALL (R4) ; get optional argument MOV #1,R3 ; if none, assume 1 (A$$RAP 1.0.3) MOV (SP)+,R0 ; retrieve number of line to skip .IFF LINSKP::MOV SP,$MFAC ; Can be in 1/8 line increments CALL (R4) ; Get optional argument MOV #DIVPL,R3 ; Default to 1 line CLR $MFAC ; Clear flag MOV #1,R0 ; No multiplycation necessary 10$: .ENDC TST R3 ; Check if arg is negative BMI 15$ ; if neg, don't make top check CMP LINEC,$HDRSW ; at top of page? BLE 30$ ; if LE yes 15$: .IF NDF R$$EIS ; If no EIS, use $MUL MOV R3,R1 ; Get into R1 for $MUL CALL $MUL ; multiply .IFF ; Otherwise, use MUL MUL R3,R0 ; Multiply .ENDC ;R$$EIS TST R1 ; Check if result is + BPL 17$ ; And continue if normal MOV R1,R2 ; Get number of lines from end of page ADD NLPG,R2 ; R2 now has line number we want to get to CMP R2,LINEC ; But check if we have already passed it BGT 16$ ; if GT, then ok MOV #DIVPL,R2 ; else just skip one line BR 20$ 16$: SUB LINEC,R2 ; Generate number of lines to skip BR 20$ 17$: MOV R1,R2 ; check if room on page ADD LINEC,R1 ; add current line CMP R1,NLPG ; room for another? BLE 20$ JMP BPAGE ; no. make a new page 20$: CALL SKIPN ; yes. space out c(r2) lines 30$: RETURN ; .DSABL LSB .sbttl FIGUR -- FIGURE COMMAND FIGUR:: CALL $FRCND ; force to end of command .IF DF A$$RAP MOV SP,$MFAC ; Can be 1/8 line increments .ENDC CALL (R4) ; get argument .IF NDF A$$RAP MOV #1,R3 ; if none, assume one line ASL R3 ; double it .IFF MOV #DIVPL,R3 ; If none, assume one line CLR $MFAC ; Clear factor flag .ENDC CMP R3,PNLPG ; check for rational argument BLOS 10$ ; if LOS okay JMP ILCM ; error 10$: MOV R3,R2 ; Get # of lines to skip .IF DF A$$RAP ADD LINEC,R3 ; Add current line count CMP R3,NLPG ; Room for figure on this page ? BLE 15$ ; Yes, skip the lines. MOV R2,-(SP) ; Save skip count CALL BPAGE ; No, break the page, then skip lines MOV (SP)+,R2 ; Restore R2 skip count. 15$: .ENDC JMP SKIPN ; space that out .sbttl FIGURE -- FIGURE COMMAND (SKIPS NEXT WHOLE PAGE) FIGURE::CALL $FRCND ; force to end of command CALL (R4) ; get argument MOV #1,R3 ; if none, assume one page INC SPFIG ; increment number of figures to skip RETURN .sbttl LITRL -- LITERAL COMMAND LITRL:: MOV (R5),LITSV ; save current flags word BIS #LITFG!SPECF,(R5) ; set literal flag MOV CMADR,LITCM ; save current expected command address MOV ELCMD,CMADR ; set address of expected command BR FILOF ; turn off fill and justify .sbttl ELTRL -- END LITERAL COMMAND ELTRL:: MOV LITSV,(R5) ; restore previous flags word MOV LITCM,CMADR ; restore previous expected command address RETURN ; .sbttl FILL AND JUSTIFY COMMANDS .sbttl JUSTN -- Enable justifying JUSTN:: BIS #JUSTF+PJUSTF,(R5) ; turn on justifying RETURN ; .sbttl JUSOF -- Disable justifying JUSOF:: BIC #PJUSTF+JUSTF,(R5) ; turn off justify bits RETURN ; .sbttl FILLN -- Enable filling FILLN:: BIS #FILLF+JUSTF,(R5) ; turn on filling, copy pjustf to justf BITNE #PJUSTF,(R5),10$ ; copy permanent flag BIC #JUSTF,(R5) ; to current one. 10$: RETURN ; .sbttl FILOF -- Disable filling FILOF:: BIC #FILLF+JUSTF,(R5) ; turn off filling and justifying RETURN ; .IF DF A$$RAP .sbttl EQON -- Enter equation mode EQON:: MOV SP,$EQMFL ; Indicate in equation mode MOV (R5),EQFLSV ; Save flags and turn off fill/justify BIC #FILLF+JUSTF,(R5) CLR R3 ; for relative argument MOV SP,$MFAC ; 1/8 line count if desired CALL (R4) ; Get test page count MOV EQTPC,R3 ; Default test page count CLR $MFAC ; Clear the switch MOV R3,-(SP) ; Save it MOV LMARG,EQLMSV ; Save left margin MOV LMARG,R3 ; Get current left margin CALL (R4) ; Get relative argument MOV LMARG,R3 ; Default to current left margin if none MOV R3,-(SP) ; Save left margin CLR R3 ; For relative argument MOV SP,$MFAC ; 1/8 lines CALL (R4) ; Get skip count MOV EQSKP,R3 ; Old skip count is default MOV R3,-(SP) ; Save it CLR R3 ; CALL (R4) ; Get new spacing count if any MOV EQSPC,R3 ; Use old one if no argument CLR $MFAC ; Clear the switch MOV NSPNG,EQSPSV ; Save current spacing MOV R3,NSPNG ; And set to equation mode spacing MOV (SP)+,R2 ; Retreive skip count BLE 10$ ; If 0 or less - don't do it CMP LINEC,$HDRSW ; In header area at top of page ? BLE 10$ ; Yes don't skip CALL SKIPN ; 10$: MOV 2(SP),R3 ; Test page BLE 20$ ; don't test page CALL TESTP ; 20$: MOV (SP)+,LMARG ; Set new left margin for equation TST (SP)+ ; pop off test page count RETURN ; return .sbttl EQOFF -- exit equation mode EQOFF:: CLR $EQMFL ; Clear equation mode indicator MOV EQFLSV,(R5) ; Restore fill/justify flags ect. MOV EQLMSV,LMARG ; Restore left margin MOV EQSPSV,NSPNG ; Restore spacing count MOV SP,$MFAC ; 1/8 line divisions CLR R3 ; For relative arg CALL (R4) ; Skip count ? MOV EQSKP,R3 ; If none use old as default CLR $MFAC ; Clear 1/8 division indicator MOV NSPNG,R2 ; Add difference between original spacing and SUB EQSPC,R2 ; EQ spacing so white space before and after BGT 5$ ; equation are equal. This doesn' work right if CLR R2 ; EQ spacing is greater than original spacing. 5$: ADD R3,R2 ; Add diff to # of lines to skip (blank). BLE 10$ ; CALL SKIPN ; skip the lines 10$: CALL DELTMP ; Delete any temporary symbols created when ; in .EQ/.EEQ mode. RETURN ; .ENDC .sbttl SETTAB -- TAB STOP SELECTION COMMAND SETTAB::CLR NTABS ; clear number of tabs MOV LMARG,R3 ; start 1st tab at lm ; others relative to prev. tab SETT1: CALL (R4) ; get another stop if any NOP ; RETURN ; INC NTABS ; point to next item MOV NTABS,R0 MOVB R3,TABTAB-1(R0) ; store this tabstop CMP R0,#TABTL-1 ; check table size BLO SETT1 ; ok. JMP ILCM ; too many tabs .IF DF A$$RAP .SBTTL OVERP -- Overprint this line OVERP:: BIS #OVPFL,$OVPSW ; Indicate over print CALL (R4) ; get argument (indentation) MOV #0,R3 ; No indent if arg absent BR OVERP1 ; Common code , more or less .sbttl OVERPJ -- Overprint right justified OVERPJ::BIS #OVPJFL,$OVPSW ; Indicate RJ overprint CALL (R4) ; Get arg for right justify MOV PRMARG,R3 ; Default is perm right margin OVERP1: MOV NSPNG,-(SP) ; save spacing CLR NSPNG ; skip 0 lines CALL OUTNJ ; break line with 0 skip BR OVERP2 ; Justifies to RM or given column .sbttl OVERB -- Over Bar command OVERB:: BIS #OVBFL,$OVPSW ; Indicate Over Bar command MOV SP,$MFAC ; arg in 1/8 lines CALL (R4) ; how high is the overbar ? 10$: MOV #DIVPL,R3 ; Default to one line CLR $MFAC ; Clear the switch CMP R3,#DIVPL ; Must be within one line BGT 10$ ; Set to one line if out of range MOV R3,-(SP) ; Save count MOV #CR,R1 ; Back up one line CALL FOUT ; MOV #ESC,R1 ; Use a negative line feed CALL FOUT ; MOV #LF,R1 ; CALL FOUT ; MOV #DIVPL,R2 ; Space down to desired overbar line SUB R3,R2 ; and skip the lines in CALL SKIPDI ; 1/8 line increments CLR R3 ; Right margin used in CENTER below BR OVERP2 ; .ENDC .SBTTL CENTER -- CENTER COMMAND ; CENTER:: .if ndf A$$RAP MOV PRMARG,R3 ; Get right margin CALL (R4) ; Get relative argument MOV PRMARG,R3 ; Default is right margin .IFF CALL (R4) ; get left margin spec MOV LMARG,R3 ; default to left margin if none given TST R3 ; Must be non-neg - no relative args BGE 5$ ; Ok 4$: JMP ILCM ; Not ok 5$: MOV R3,-(SP) ; Save till we get right margin CALL (R4) ; get relative argument MOV PRMARG,R3 ; default is permanent right margin MOV (SP)+,R0 ; Retreive left margin spec CMP R0,R3 ; Left margin must be less than or equal to right BGT 4$ ; It's not - report error ! CMP R3,PRMARG ; Right must be less than permanent margin BGT 4$ ; It's not - report error ! SUB LMARG,R0 ; Set up right margin spec so it works with ADD R0,R3 ; Left margin offsetting below - OVERP2: .ENDC MOV R3,-(SP) ; store CALL $FRCND ; force to logical end of command CMPNE #CR,R1,CENT1 ; not end of line? 10$: CALL GCIN ; discard rest of this command CMPNE R1,#LF,10$ ; not line feed? CENT1: CALL GCIN ; read line to be centered CMPEQ R1,#CR,CENT2 ; carriage return? CALL WLNIN1 ; put in line input buffer BR CENT1 ; loop for more CENT2: MOV (SP)+,R2 ; compute spacing before line .IF DF A$$RAP BITNE #OVPFL,$OVPSW,50$ ; Skip Justify if overprint BITNE #OVBFL,$OVPSW,25$ ; Go output the overbars .ENDC SUB LIBUF+BF.LEN,R2 ; Less length of line SUB LMARG,R2 ; minus left margin ADD NSPCH,R2 ; including underlines, etc .IF DF A$$RAP BITNE #OVPJFL,$OVPSW,50$ ; Don't center .ENDC ASR R2 ; take half .IF DF A$$RAP 25$: .ENDC ADD LMARG,R2 ; add in left margin ADD RIGSHI,R2 ; Add on right shift space ADD EBSIZ,R2 ; Add on change bar area CALL NSPAC ; output spaces MOV #LIBUF+BF.ADR,R4 ; then output line buffer to file CALL PSTRPA ; .. MOV LIBUF+BF.ADR,LIBUF+BF.PTR ; Reset buffer CLR LIBUF+BF.LEN ; ... .IF DF A$$RAP BITNE #OVBFL,$OVPSW,40$ ; If overbar space back to original pos. .ENDC CALL SKIPS ; skip one line .IF DF A$$RAP BR 60$ ; return 40$: MOV (SP)+,R2 ; Retreive # of lines to restore position CALL SKIPDI ; and skip down BR 55$ ; return 50$: MOV (SP)+,NSPNG ; restore spacing MOV R2,INDCT ; Right justify with indentation count 55$: MOV #CR,R1 ; do a carriage return CALL FOUT ; CLR $OVPSW ; Clear flags 60$: ; .ENDC RETURN ; Return to caller .SBTTL FOOTN -- FOOTNOTE COMMAND FOOTN:: CALL (R4) ; how many lines to reserve? 5$: JMP ILCM ; must have spec MOV R3,R1 ; Place in R1 .IF NDF A$$RAP ASL R1 ; And double it .IFF ASH #MUL8,R1 ; Mul by 8 for check .ENDC CMP R1,PNLPG ; value within reason? BHI 5$ ; if HI no .IF NDF A$$RAP MOV NSPNG,R0 ; reserve n times spacing .IF NDF R$$EIS ; If no EIS, use $MUL MOV R3,R1 ; Get into R1 for $MUL CALL $MUL ; multiply .IFF ; Otherwise, use MUL MUL R3,R0 ; Multiply .ENDC ;R$$EIS .ENDC .IF DF A$$RAP MOV LINEC,R2 ; See if room for this footnote ADD FOOTC,R2 ; Plus footnotes already declared ADD R1,R2 ; Plus this footnote ADD NSPNG,R2 ; Plus current line to output ADD NSPNG,R2 ; Plus a normal spacing count CMP R2,NLPG ; Less than page length ? BLO 6$ ; yes SAVE R0,R1,R2,R3,R4,R5 CALL SAVLIB ; Save LIBUF contents till after page break UNSAVE R0,R1,R2,R3,R4,R5 6$: .ENDC ADD R1,FOOTC ; add to reserved footnote lines ; Allocate space in free list MOV #80.,R0 ; Set length .IF NDF R$$EIS ; If no EIS available, use $MUL MOV R3,R1 ; Get # of lines CALL $MUL ; Get buffer size to allocate .IFF ; Otherwise, use MUL MUL R3,R0 ; Get buffer size to allocate .ENDC ;R$$EIS ADD #FN.SIZ,R1 ; Add in additional overhead MOV R1,R3 ; Save buffer size -> R3 CALL ALLOC ; Allocate buffer space ; Add item to footnote list 1$: MOV FOOTLH,R2 ; Point to list head BEQ 3$ ; EQ - then init back pointer 2$: MOV R2,R0 ; MOV FN.FWD(R0),R2 ; Get next link BNE 2$ ; NE - then check next link MOV R1,FN.FWD(R0) ; Set foward pointer from last element MOV R0,FN.BCK(R1) ; Set back pointer CLR FN.FWD(R1) ; Set up foward pointer BR 4$ ; Create the first list entry 3$: MOV R1,FOOTLH ; Save list head CLR FN.FWD(R1) ; Clear foward pointer CLR FN.BCK(R1) ; Clear back pointer ; Build buffer header 4$: MOV R1,R2 ; Save pointer ADD #FN.SIZ,R2 ; Point beyond list header MOV R3,-(SP) ; Save length of buffer SUB #FN.SIZ,(SP) ; Get length remaining MOV #FOOTP1,R3 ; Point to buffer header MOV R2,BF.ADR(R3) ; Set footnote pointers MOV R2,BF.ADR+4(R1) ; Point to start MOV R2,BF.PTR(R3) ; Point to next avail. slot MOV R2,BF.PTR+4(R1) ; ... MOV R2,BF.END(R3) ; Set up pointer to ADD (SP)+,BF.END(R3) ; Point to end MOV BF.END(R3),BF.END+4(R1) ; ... CLR BF.LEN+4(R1) ; And reset length CLR BF.LEN(R3) ; ... CALL $FRCND ; force to logical end of line CLRB GCSCH ; clear terminal character .IF DF A$$RAP MOV #'!,FNCHAR ; Set default footnote terminator CMPEQ #CR,R1,7$ ; At end if cr found - else set to terminator MOV R1,FNCHAR ; 7$: .ENDC CMPNE #CR,R1,40$ ; not end of line? 10$: CALL CCIN ; skip rest of command line CMPNE R1,#LF,10$ ; not line feed? BR 40$ ; 20$: CALL CCIN ; read a character 30$: MOV #FOOTP1,R4 ; Point to footnote header CALL WCI ; Write character in buffer BCS 60$ ; CS - then buffer overflowed CMPNE R1,#LF,20$ ; not end of line? 40$: CALL CCIN ; see what character after line feed is CMPEQ R1,#EOF,50$ ; end of file? .IF NDF A$$RAP CMPNE #'!,R1,30$ ; not end of footnote? .IFF CMPNE FNCHAR,R1,30$ ; not end of footnote? .ENDC 45$: MOV #EOF,R1 ; set end of footnote 50$: MOV #FOOTP1,R4 ; Point to footnote header CALL WCI ; Write character in buffer BCS 60$ ; CS - then buffer overflowed MOV FOOTLH,R2 ; Get list head 55$: MOV R2,R0 ; Get last pointer MOV FN.FWD(R0),R2 ; Search for list end BNE 55$ ; Loop till found MOV FOOTP1+BF.LEN,BF.LEN+4(R0) ; Update length MOV FOOTLH,R0 ; Get pointer again MOV BF.ADR+4(R0),FOOTP1+BF.ADR ; Restore head of list MOV BF.PTR+4(R0),FOOTP1+BF.PTR ; ... MOV BF.END+4(R0),FOOTP1+BF.END ; ... MOV BF.LEN+4(R0),FOOTP1+BF.LEN ; ... RETURN ; Return to caller ; Footnote buffer has overflowed, tell user about it ; and flush rest of footnote. 60$: DIAG FTNOVF ; Say it overflowed 62$: CALL CCIN ; Read a character CMP R1,#EOF ; End of file ? BEQ 65$ ; EQ - then terminate footnote .IF NDF A$$RAP CMP R1,#'! ; End of footnote ? BNE 62$ ; NE - then continue reading .IFF CMPNE R1,FNCHAR,62$ ; Not end of footnote - continue reading .ENDC 65$: MOV #FOOTP1,R4 ; Point to footnote buffer SUB #4,BF.PTR(R4) ; Point back a character SUB #4,BF.LEN(R4) ; ... MOV #CR,R1 ; Output a CR-LF CALL WCI ; ... MOV #LF,R1 ; ... CALL WCI ; ... BR 45$ ; And resume .sbttl PERIOD SPACING COMMANDS .SBTTL PERSP -- Enable period spacing PERSP:: MOV SP,$PERSW ; enable two spaces after punctuation RETURN ; .sbttl NPERS -- Disable period spacing NPERS:: CLR $PERSW ; disable two spaces after punctuation RETURN ; .sbttl SHFUC -- COROUTINE TO SHIFT TO UPPER CASE TEMPORARILY SHFUC:: MOV (SP),-(SP) ; copy return address MOV CAS,2(SP) ; save current case CLR CAS ; set for upper case CALL @(SP)+ ; call the caller back MOV (SP)+,CAS ; restore previous case RETURN ; .sbttl DATE -- DATE COMMAND DATE:: CALL $FRCND ; force to logical end of command CMPNE #CR,R1,DATE1 ; not end of line? 10$: CALL GCIN ; discard reset of this command CMPNE R1,#LF,10$ ; not a line feed? DATE1: MOV #DATEBF,R0 ; get address of buffer 20$: CALL GCIN ; read character CMPEQ R1,#CR,DATE2 ; is it carriage return CMPEQ R0,#DATEBF+16.,DATE3 ; too many characters MOVB R1,(R0)+ ; store character BR 20$ ; get rest DATE2: MOV R0,R2 SUB #DATEBF,R0 ; get number of characters MOV R0,DATECT ; store number of characters 40$: CMP R0,#16. BGE 30$ MOVB #' ,(R2)+ INC R0 BR 40$ 30$: MOV #1,$DATE ; save have date RETURN DATE3: CALL GCIN ; get character CMPNE R1,#CR,DATE3 ; c/r? BR DATE2 ; yes return .DSABL LSB .sbttl DATET -- TABLE OF CONTENTS DATE COMMAND DATET:: CALL $FRCND ; force to logical end of command CMPNE #CR,R1,DATE1T ; not end of line? 10$: CALL GCIN ; discard reset of this command CMPNE R1,#LF,10$ ; not a line feed? DATE1T: MOV #DATTBF,R0 ; get address of buffer 20$: CALL GCIN ; read character CMPEQ R1,#CR,DATE2T ; is it carriage return CMPEQ R0,#DATTBF+16.,DATE3T ; too many characters MOVB R1,(R0)+ ; store character BR 20$ ; get rest DATE2T: MOV R0,R2 SUB #DATTBF,R0 ; get number of characters MOV R0,DATTCT ; store number of characters 40$: CMP R0,#16. BGE 30$ MOVB #' ,(R2)+ INC R0 BR 40$ 30$: MOV #1,$DATET ; save have date RETURN DATE3T: CALL GCIN ; get character CMPNE R1,#CR,DATE3T ; c/r? BR DATE2T ; yes return .sbttl INDIRC -- INDIRECT FILE PROCESSING INDIRC:: MOV R1,-(SP) ; save R1 MOV #80.,R1 ; allocate 80. byte buffer. CALL ALLOC ; allocate it. MOV R1,R0 ; point to buffer. MOV (SP)+,R1 ; recover R1 MOV R0,-(SP) ; save beginning of buffer. MOV #80.,-(SP) ; (SP)->end of buffer ADD R0,(SP) ; 10$: BITB #CHASP,CHATBL(R1) ; Is it a spacing character? BNE 20$ ; NE - yes CMPEQ #CR,R1,35$ ; stop at end of line CMPEQ #'!,R1,30$ ; or at start of comment MOVB R1,(R0)+ ; save the character CMPEQ R0,(SP),30$ ; stop if buffer is full 20$: CALL GCIN ; get the next character BR 10$ ; check next character 30$: CALL GCIN ; flush the rest of the line CMPNE #CR,R1,30$ ; 35$: TST (SP)+ ; clear the stack MOV R0,R1 ; length of name => R1 MOV (SP)+,R0 ; R0-> name SUB R0,R1 ; BLE 40$ ; ignore if no file name CALL PSHFIL ; save current file info BCS 40$ ; ignore if too deep CALL NEWFIL ; open the new file 40$: MOV R0,R1 ; file name buffer into R1 CALL FREE ; free it MOVB #CR,GCSCH ; force end of line on helpless thing RETURN ; and done. .SBTTL SETN - SET NUMERIC VALUE ; SETN:: MOV R4,-(SP) ; Save R4 while we use CCIN. 5$: CALL CCIN ; Try to read a character BITB #CHASP,CHATBL(R1) ; Is it a spacing character? BNE 5$ ; Yes - loop until nonspacing char. MOV #,-(SP) ; Save the maximum length of name. MOV #BUFR,R2 ; Point to the buffer area. BITB #CHALC!CHAUC,CHATBL(R1) ; Legal character? BEQ 99$ ; no, error. BICB #40,R1 ; Raise to upper case just in case. MOVB R1,(R2)+ ; Get first part of name. 10$: CALL CCIN ; Get a character. BITB #CHALC!CHAUC!CHANU,CHATBL(R1) ; Is it legal for an ident? BEQ 20$ ; EQ - no DEC (SP) ; Any more characters left? .IF NDF A$$RAP BMI 10$ ; No - just ignore trailing characters .IFF BMI 99$ ; Report error if too many characters for ident .ENDC BITB #CHALC,CHATBL(R1) ; Is it lower case? BEQ 15$ ; No - don't try to raise it to upper BICB #40,R1 ; Yes - raise to upper case. 15$: MOVB R1,(R2)+ ; Yes - output it. BR 10$ ; And get the rest of the symbol. 20$: TST (SP)+ ; Discard symbol length. CLRB (R2)+ ; Pad the symbol with 30$: BITB #CHASP,CHATBL(R1) ; Is the character space? BEQ 40$ ; No - just skip. CALL CCIN ; Yes - get next character. BR 30$ ; And loop. 40$: CMPB R1,#'= ; Is it an = sign? BNE 99$ ; No -- error. MOV (SP)+,R4 ; Recover R4 CALL (R4) ; Call the appropriate routine. JMP 99$ ; Illegal if nothing there. MOV R3,R0 ; Get the value into R0 MOV #BUFR,R1 ; Point to the buffer from R1 CALL SETINT ; Set an integer value RETURN ; And return to the caller. 99$: JMP ILCM ; Illegal command DATA RNCMDD BUFR: .BLKB 8. ; Room for symbol buffer. CODE RNCMD .IF DF A$$RAP .SBTTL SUBD - SET STRING VALUE TO BE SUBSTITUTED, DELIMITED SEARCH SUBSTD:: MOV #DLTSYM,SYMMSK ; Indicate delimited search BR SUBCOM ; Go to common code .SBTTL SUB - SET STRING VALUE TO BE SUBSTITUTED ; SUBST:: CLR SYMMSK ; Indicate not delimited search SUBCOM: ; Common code TSTEQ $EQMFL,5$ ; In equation mode ? BIS #TMPSYM,SYMMSK ; Yes ,indicate delete symbol when .EEQ reached 5$: MOV R4,-(SP) ; Save R4 while we use CCIN. 6$: CALL CCIN ; Try to read a character BITB #CHASP,CHATBL(R1) ; Is it a spacing character? BNE 6$ ; Yes - loop until nonspacing char. MOV #,-(SP) ; Save the maximum length of name. MOV #BUFR,R2 ; Point to the buffer area. CMPEQB R1,#'=,900$ ; If first character is '=', error MOVB R1,(R2)+ ; Get first part of name. 10$: CALL CCIN ; Get a character. BITNEB #CHASP,CHATBL(R1),20$ ; Exit loop if spacing character CMPEQB R1,#'=,20$ ; Exit loop if '=' found DEC (SP) ; Any more characters left? BMI 900$ ; Error if too many characters for ident MOVB R1,(R2)+ ; Yes - output it. BR 10$ ; And get the rest of the symbol. 20$: TST (SP)+ ; Discard symbol length. CLRB (R2)+ ; Pad the symbol with 30$: BITB #CHASP,CHATBL(R1) ; Is the character space? BEQ 40$ ; No - just skip. CALL CCIN ; Yes - get next character. BR 30$ ; And loop. 40$: CMPB R1,#'= ; Is it an = sign? BNE 900$ ; No -- error. ; ; Scan for string - first character is a delimiter - scan will ; proceed until like delimiter is found or end of line (). ; 200$: CALL CCIN ; search for delimiter BITNEB #CHASP,CHATBL(R1),200$ ; loop if spacing character ; ; Non spacing character - must be punctuation for valid delimiter ; CMP #SPC,R1 ; Must be greater than 'space' BGE 900$ ; it's not - error BITNEB #CHALC!CHAUC!CHANU,CHATBL(R1),900$ ; error if not punctuation MOV R1,-(SP) ; save the delimiting character MOV #BUFR2,R2 ; Move string into BUFR2 210$: CALL CCIN ; Get next character CMPEQ R1,(SP),300$ ; Match on delimiter CMP #SPC,R1 ; If greater than 'space' it's ok BLE 230$ ; Move to output buffer BITEQB #CHAEC,CHATBL(R1),230$ ; Not end-of-command character, continue MOV R1,GCSCH ; Store break character BR 310$ ; Enter symbol in table 230$: CMP R2,#BUF2ND ; At end of temp buffer ? BGE 900$ ; Yes string too long CMPEQB #'|,R1,240$ ; Command/text separartor - insert MOVB R1,(R2)+ ; No - move character to temp buffer and BR 210$ ; get the next character in string 240$: MOVB #CR,(R2)+ ; Carriage return followed by MOV #LF,R1 ; Line feed - loop to check enough room BR 230$ ; ; 300$: 310$: TST (SP)+ ; Clear delimiter MOV (SP)+,R4 ; Restore R4 MOV #BUFR2,R0 ; Address of string variable SUB R0,R2 ; # of characters in string MOV #BUFR,R1 ; Address of string variable name CALL SETCHA ; Enter into symbol table RETURN ; Return to caller 900$: JMP ILCM ; Illegal command DATA RNCMDD BUFR2: .BLKB 40. ; Room for string buffer. BUF2ND: ; End of buffer CODE RNCMD .ENDC ; Change metacharacter command ; ; This command allows the user to change any ; metacharacter to any other metacharacter, with ; some exceptions. Unfortunately, RNO does not ; perform properly when ; or . are renamed, and ; the execution could become difficult to understand ; if it renamed to an already existing metacharacter, ; so these cases are prevented. ; CHANG: CALL $FRCND ; Get next item in command. CALL GCIN ; Get first character of mnemonic CMP R1,#140 ; Lower case character BLT 1$ ; Upper case SUB #40,R1 ; Make upper case 1$: MOV R1,R0 ; Save the character CALL GCIN ; Get second character of mnemonic CMP R1,#140 ; Make upper case if necessary BLT 2$ SUB #40,R1 2$: SWAB R1 ; Put the two characters together BIS R1,R0 ; Cram the two characters together. MOV METNUM,R3 ; Get number of mnemonics MOV #METNUM,R2 ; Get location of last mnemonic 10$: CMP R0,-(R2) ; Compare mnemonic BEQ 20$ ; Found a match leave SOB R3,10$ DIAG BADMET ; Say not found. RETURN ; And return. 20$: DEC R3 ; Make into a 0-origin offset. ROL R3 ; Make into word address MOV R3,-(SP) ; Save this location CLRB GCSCH ; Force skipping previous char. CALL $FRCND ; Get next item in command. BITB #CHAEC,CHATBL(R1) ; Is it an end-of-command character? BNE 40$ ; NE - yes, we can't alter those! CLR R3 ; Get beginning of metacharacters. MOV METNUM,R2 ; Get count of metacharacters. 30$: CMP R1,METBEG(R3) ; Found a match? BNE 35$ ; No - this one's OK CMP R3,(SP) ; Are we changing a metacharacter ; to itself? BNE 40$ ; J if not - duplicate metacharacter. 35$: ADD #2,R3 ; Get to next matacharacter. SOB R2,30$ ; And loop over all metacharacters. MOV (SP)+,R3 ; Recover R3 MOV R1,METBEG(R3) ; Change to new metacharacter. RETURN ; And return. 40$: MOV (SP)+,R3 ; Recover R3 DIAG DUPMET ; Duplicate metacharacter RETURN ; And return. 50$: DIAG ILLMET ; Can't change this metacharacter. RETURN .SBTTL SWPFIL -- Swap output file ;+ ; This command enables the user to swap the output ; from the .LST file to the .TOC file and back again. ; This allows title pages to be output to the TOC ; with little overhead. ;- SWPFIL:: CALL $FRCND ; Force to end of command 10$: CALL CCIN ; Get next char. CMPB R1,#'a ; Is it lower case ? BLO 20$ ; Maybe CMPB R1,#'z ; Check upper range BHI 20$ ; HI - then it's not lower case SUB #40,R1 ; Convert to upper case 20$: CMPB R1,#'T ; Change to TOC ? BEQ 30$ ; EQ - yes CALL FORM ; Break page CALL OUTPUT ; Flush the buffer CLRB $SWPFL ; Reset flag MOV SAVLCT,LINEC ; Restore current line count BR 40$ ; And go to next command 30$: TSTB TOCSPC ; Is a TOC file active ? BNE 32$ ; NE - yes DIAG NOTOC ; Else say so CLRB $SWPFL ; Reset flag BR 40$ ; And go flush remainder of command 32$: MOV LINEC,SAVLCT ; Save line count CALL OUTPUT ; Flush buffer CALL TOTPUT ; Do TOC also COMB $SWPFL ; Say to switch to .TOC file 40$: CALL CCIN ; Get another character CMPB R1,#CR ; Carriage return ? BEQ 50$ ; EQ - then return CMPB R1,#'; ; Semi-colon ? BEQ 40$ ; EQ - then return CMPB R1,#'. ; Another command ? BNE 40$ ; NE - then get next character 50$: MOVB R1,GCSCH ; Save break character RETURN ; And return DATA RNCMDA SAVLCT: .BLKW 1 ; Saved line count CODE RNCMD .sbttl PRNTLN -- Print message to user. ;+ ; This command allows the user to pass a message ; back to the user when processing a file. (i.e. current ; version of document, special switches, etc.) ;- PRNTLN:: CALL $FRCND ; Force to end of command MOV #MSGBF,R4 ; Point to the buffer MOV BF.ADR(R4),BF.PTR(R4) ; Reset secondary buffer CLR BF.LEN(R4) ; ... 10$: CALL CCIN ; Read a character CMPB R1,#CR ; Carriage return ? BEQ 20$ ; Yes, then go output the message CALL WCI ; Insert character into output buffer BR 10$ ; Loop till thru 20$: DIAG USRMSG ; Output user message MOV BF.ADR(R4),BF.PTR(R4) ; Clear title buffer CLR BF.LEN(R4) ; ... RETURN ; Return .END