.TITLE RUNOFF .IDENT /BL7.0/ ; ; ; AUTHOR: L. WADE 1-JUN-72 ; ; MODIFIED BY: ; ; E. POLLACK U. OF W. 19-DEC-73 ; ; D. N. CUTLER 27-JUL-75 ; ; ; BONNER LAB MODIFACATIONS ; ADDED OPTIONAL ESCAPE SEQUENCE HANDLING ; Substitution flags, Layout, Most DSR commands ; Table driven parsing, Rewrote most sections!!!! ; ; J. CLEMENT November 1982 ; ; THIS PROGRAM WAS TRANSLATED FROM THE PDP-10 VERSION OF RUNOFF ; AUTHORED BY B. CLEMENTS. ; NOTES ON REGISTER USAGE ; R0,R1 are completely volatile ; In general subroutines need not save them ; R2-R5 Should be saved if they are used ; R0 Input parameter ; R1 CURRENT CHARACTER ; R2 SPACE/LINE COUNT ; R3 USED AS BUFFER HEADER ADDRESS ; R4 SUBROUTINE ADDRESS FOR COMMAND EXECUTION ; J. CLEMENT AUG 82 ; ; LOCAL MACROS ; ; ; Initial switch setting tables ; .const RMTAB: .ASCII /IVXLCDM/ ; Roman numeral table .even INI$SW::.WORDA TTSW!CRSW!HYPSW!FFDSW; Initial value for $SWTCH IUL:: .if df rt11 .rad50 /L/ .endc .if ndf rt11 .asciz /L/ ; Initial underline switch .endc .even .vars SPSAV:: .blka 1 ; Saves initial stack pointer ; ; UP/DOWN escape sequences ; UPTAB:: .BYTE ESC,ES.NUL ; Multiple escape processing UPMOV:: .BLKB SUPSIZ+1 ; Move text up 1/2 space DNTAB:: .BYTE ESC,ES.NUL ; Multiple escape processing DNMOV:: .BLKB SUPSIZ+1 ; Move text down 1/2 space VARESC::.BLKB VARSIZ+1 ; Holds variable spacing string $OUTSW::.BLKB 1 ; Zero if output enabled .EVEN $SWTCH::.BLKA 1 ; Input switch ; ; General input switches and variables ; VARBEG:: ; This marks first variable ULSWT:: .BLKA 1 ; Underline stat RIGSHI::.BLKA 1 ; Right shift for text $IFUSW::.BLKB 1 ; If unconditional switch $HDSTS::.BLKB 1 ; Auto header status (0=enabled) $DEBSW::.BLKB 1 ; Debug switch $HDRSW::.BLKB 1 ; DISABLE PAGE HEADER (0=NO) $PAGNG::.blkb 1 ; Non zero if no paging $FIRPG::.BLKB 1 ; Non zero if first page of document $PAGPD::.BLKB 1 ; Page pending $PAGBR::.BLKB 1 ; 0=AT TOP OF PAGE $ULMSW::.BLKB 1 ; UNDERLINE MODE (-1=Line,0=BS,1=simulate) $FOTPD::.BLKB 1 ; FOOTNOTE PENDING (0=NO) $PFOOT::.BLKB 1 ; Permanent footnote in progress $ULOSW::.BLKB 1 ; UNDERLINE OUTPUT? (0=NO) $ULCH:: .ASCII /_/ ; UNDERLINE CHARACTER $SEPR:: .ASCII /-/ ; separator character CSMOR::.BLKB 1 ; Non zero if more input files pending EOFSW::.BLKB 1 ; NON ZERO IS END OF FILE $GCEND::.BLKB 1 ; Non zero for immediate input stop $AUTTL::.BLKB 1 ; Autotitle active (0=yes) $AUSTL::.BLKB 1 ; Autosubtitle (0=NO) $LAYOU: .BLKB 1 ; Layout value NXLAY:: .BLKB 1 ; Next layout parameter PRLAY:: .BLKB 1 ; Permanent layout parameter CHLAY:: .BLKB 1 ; Chapter layout parameter $ELIPS::.BLKB 1 ; Non zero enables ellipses $TABLF::.BLKB 1 ; 0=Left justify tabs , Non=Right justify $TOCBE::.BLKB 1 ; Non zero if TOC Begun $SEQSW::.BLKB 1 ; Separated equation mode on (0=no) $NOSPC::.BLKB 1 ; If non zero converts spaces to NXS $HSPSW::.BLKB 1 ; If zero enables half spacing $KEEPL::.BLKB 1 ; Keep blank filled lines $KEEPT::.BLKB 1 ; Keep leading tabs RETSW:: .BLKB 1 ; Non zero return from GCIN on #=|sp tab $VARSP::.BLKB 1 ; Non zero if variable spacing active $FONT:: .BLKB 1 ; Font number $UNLRS::.BLKB 1 ; Non zero if must reset underline buffer $NUMSW::.BLKB 1 ; NUMBER PAGES (0=yes) $ODPAG::.BLKB 1 ; Produce odd numbered pages $SETPG::.BLKB 1 ; Page has been set $SBPSW::.BLKB 1 ; SUBPAGE MODE ACTIVE (0=NO) HYPOP:: .BLKB 1 ; Hyphenation option $COLMN::.BLKB 1 ; Number of columns $COLCT::.BLKB 1 ; Column count .EVEN $COLMR::.BLKA 1 ; Column margin HYPLO:: .BLKA 1 ; Chars in front of autohyphenation HYPHI:: .BLKA 1 ; Chars in back HYPSZ:: .BLKA 1 ; Minimum size word for autohyphenation VUNIT:: .BLKA 1 ; Spacing units HUNIT:: .BLKA 1 ; Spacing units $IFSTK::.BLKA IFDPTH+1 ; Number of nested ifs $IFSTT::.BLKB IFDPTH ; If status .even ; ; SWITCH PARAMS ; LOWPAG::.BLKA 1 ; Lowest page number to print HGHPAG::.BLKA 1 ; Highest page number to print LOWCHP::.BLKA 1 ; lowest chapter to print HGHCHP::.BLKA 1 ; highest chapter to print LOWAPN::.BLKA 1 ; lowest appendix to print HGHAPN::.BLKA 1 ; highest appendix to print PAGHD:: .BLKB CH.HD1+1 ; Page number text prototype PAGH2:: .BLKB CH.HD2+1 ; Second page header prototype TTLHD1::.BLKB CH.HD1+1 ; Title headers TTLHD2::.BLKB CH.HD2+1 ; Title headers STLHD1::.BLKB CH.HD1+1 ; Subtitle headers STLHD2::.BLKB CH.HD2+1 ; Subtitle headers APNMG:: .BLKB CH.HD1+1 ; Appendix header text CHPMG:: .BLKB CH.HD1+1 ; Chapter header text .blkb LEVSIZ* ; Level headers APNM2:: .BLKB CH.HD2+1 ; Appendix trailing text CHPM2:: .BLKB CH.HD2+1 ; Chapter trailing text .blkb LEVSIZ* ; Level trailers .EVEN LPPG:: .BLKA 1 ; Hardware lines per page ; ; SWITCH FLAGS (WORD) ; TJFSW: .BLKA 1 ; TEMPORARY JUSTIFY FLAG (0=NO) ; ; FLAG WORDS ; ; BYTE 0= The character to test (flag character) ; BYTE 1= 0 Flag enabled ; 200 Disabled by NO FLAG command ; 100 Disabled for literal ; ; Enable bit saved for SAVE command ; FLGBEG: $AFLSW::.blka 1 ; FLAG ACCEPT (-=NO) $BRFSW::.blka 1 ; break flag switch $CFLSW::.blka 1 ; FLAG CAPITALIZE ENABLE (-=NO) $EFLSW::.blka 1 ; ESCAPE FLAG $EQFSW::.blka 1 ; Equation flag switch $HFLSW::.blka 1 ; FLAG HYPHENATE (-=NO) $IFLSW::.blka 1 ; INDEX FLAG ENABLE (-=NO) $LFLSW::.blka 1 ; LOWERCASE SWITCH (-=NO) $PFLSW::.blka 1 ; Period flag $OFLSW::.blka 1 ; OVERSTRIKE FLAG ENABLE (-=NO) $QFLSW::.blka 1 ; QUOTED SPACE SWITCH (-=NO) $SBFSW::.blka 1 ; substitute flag switch $SFLSW::.blka 1 ; UPPERCASE SHIFT SWITCH (-=NO) $SIFSW::.blka 1 ; Subindex flag enable $SPFSW::.blka 1 ; Special flag switch $TBFSW::.blka 1 ; Tab flag $UFLSW::.blka 1 ; UNDERLINE SWITCH (-=NO) nflags==<.-$AFLSW>/$WORDL ; Number of flags $NFLSW::.blka 1 ; CONTROL FLAG ; ; ; ALL VARIABLES BETWEEN SAVBEG/SAVEND ARE SAVED DURING FOOTNOTING ; SAVBEG==. ; DISABLE SWITCHES (0=ENABLED) (200=DISABLED) (100=OFF)(1=OFF FOREVER) ; ; Switch table saved by SSTAT (only .DIS bits) ; SWITS: $AUBRK::.BLKB 1 ; Autobreak disabled (0=yes) $AUHYP::.BLKB 1 ; Autohyphenation disabled (0=enabled) $AUTSW::.BLKB 1 ; Autoparagraph active (0=NO,-=autopar,+=table) $CBRSW::.BLKB 1 ; CHANGE BAR SWITCH $CONT:: .BLKB 1 $ESCSW::.BLKB 1 ; ESCAPE SEQUENCES DISABLED $EQUSW::.BLKB 1 ; Equation mode on ? (0=yes) $HYPSW::.BLKB 1 ; Non zero disable hyphenation $INXSW::.BLKB 1 ; INDEXING ENABLED $OVRSW::.BLKB 1 ; OVERSTRIKING DISABLED $PERSW::.BLKB 1 ; Double spaces after punctuation (0=NO) $SUBSW::.BLKB 1 ; substitute disabled flag $TABSW::.BLKB 1 ; NON ZERO DISABLES TABS $TOCSW::.BLKB 1 ; Zero if TOC enabled $UNLSW::.BLKB 1 ; UNDERLINING OFF NSWITS=.-SWITS ; Number of switches ; ; Not saved in status ; CHBAR:: .BLKB 1 ; Default bar character $UNLLN::.BLKB 1 ; Counts underlines pending $TABPD::.BLKB 1 ; Right justified tab pending $CENSW::.BLKB 1 ; NON ZERO = CENTER TEXT $RIGSW::.BLKB 1 ; Non zero = right justify text $BRKSW::.BLKB 1 ; Non zero = break at end of line $USRCM::.BLKB 1 ; Non zero = search user commands first $TRZER::.BLKB 1 ; Non zero = no trailing zero HYPCT: .BLKB 1 ; Counts hyphenated lines .EVEN ; (Set by VARSET) CASE:: .BLKB 1 ; -=LOWER CASE ONLY, +=UPPER CASE ONLY ; *** ULOCK:: .BLKB 1 ; Saves permanent case lock .BLKA ; Extra for VMS TTLCAS::.BLKA 1 ; Title case STLCAS::.BLKA 1 ; Subtitle case ; ; The following 3 variables are saved by permanent footnotes ; PFSBEG:: F.1:: .BLKA 1 ; Flag word NSPNG:: .BLKA 1 ; SPACING BETWEEN LINES LMARG:: .BLKA 1 ; CURRENT LEFT MARGIN RMARG:: .BLKA 1 ; CURRENT RIGHT MARGIN PFSEND: ; End of permanent footnote save PFSIZ==PFSEND-PFSBEG ; Number of bytes to save CMARG:: .BLKA 1 ; MARGIN FOR CENTERING TEXT ; ; Variables saved by VARSAV and set by VARSET ; ; Note: SPCH,LSPCH,LINBK are all specified in character units ; LCH:: .BLKB 1 ; LAST CHAR LSCH:: .BLKB 1 ; Last char before space (break) .even BRCNT:: .BLKA 1 ; number of breaks this line CASSAV::.BLKA 1 ; SAVE CASE AT LAST SPACE ESCCNT::.BLKA 1 ; COUNTS ESCAPE SEQUENCES LESMSK::.BLKA 1 ; Last escape stack LINBK:: .BLKA 1 ; Space left this line LSPCH:: .BLKA 1 ; Space occupied before last space LTAB:: .BLKA 1 ; Address of last tab output count LUNLSW::.BLKA 1 ; Underline switch at last space OVRCT:: .BLKA 1 ; COUNTS BACKSPACE ABORTS SPCH:: .BLKA 1 ; Space occupied this line SPCNSV::.BLKA 1 ; Same before last space SPCNT:: .BLKA 1 ; Expandable space count ; ; Saved by VARSAV ; HYPSP:: .BLKA 1 ; Non zero if hyphenation point exists PHSP:: .BLKA 1 ; Permanent horizontal spacing LPHSP:: .BLKA 1 ; Last permanent horizontal spacing LSTSP:: .BLKA 1 ; Address of char before last space in output INDCT:: .BLKA 1 ; CURRENT INDENTATION EBSIZ1::.BLKA 1 ; Change bar initital indentation EBSIZ2::.BLKA 1 ; Change bar second indentation ESMSK:: .BLKA 1 ; Address of current location in escape stack CURVS:: .BLKA 1 ; Current vertical spacing MAXVS:: .BLKA 1 ; Max vertical spacing MINVS:: .BLKA 1 ; Min vertical spacing SAVEND=. SAVSZ==SAVEND-SAVBEG ; SIZE OF FOOTNOTE SAVE BUFFER ; ; MISC SWITCHES ; TESMSK::.BLKA 1 ; Temporary escape mask $PAGSW::.BLKA 1 ; OUTPUT 'PAGE' SWITCH (0=YES) $CHPSW::.BLKA 1 ; output chapter (0 = yes) ; ; INPUT ADDRESS POINTERS ; LNINS:: .BLKA 1 ; ADDRESS OF LAST CHAR IN LINE LSPIN:: .BLKA 8. ; ADDRESSES OF LAST INPUT SPACE LSSTK:: .BLKA 1 ; last input stack value ; ; Page format variables ; $NTITL::.BLKA 1 ; non zero prevents title in header TMARG:: .BLKA 1 ; CURRENT TOP MARGIN HSPAC:: .BLKA 1 ; CURRENT HEADER SPACING PRMRG:: .BLKA 1 ; PERMANENT RIGHT MARGIN PLMRG:: .BLKA 1 ; PERMANENT LEFT MARGIN PTMRG:: .BLKA 1 ; PERMANENT TOP MARGIN PSPNG:: .BLKA 1 ; Permanent spacing PHSPOU::.BLKA 1 ; Permanent output horizontal spacing EQSPC:: .BLKA 1 ; Equation spacing $EOPSP::.BLKA 1 ; Current End of page spacing NXEPSP::.BLKA 1 ; Next End of page spacing PREPSP::.BLKA 1 ; Permanent End of page spacing CHEPSP::.BLKA 1 ; Chapter End of page spacing APNDSP::.BLKA 1 ; appendix display format CHPDSP::.BLKA 1 ; chapter display format .BLKA LEVSIZ ; Level display formats PAGDSP::.BLKA 1 ; page number display format SUBDSP::.BLKA 1 ; subpage display format (letter) PAGNX:: .BLKA 1 ; next page number SUBNX:: .BLKA 1 ; next subpage APNNX:: .BLKA 1 ; next appendix number CHPNX:: .BLKA 1 ; next chapter number PAGENO::.BLKA 1 ; CURRENT PAGE NUMBER SUBPGE::.BLKA 1 ; current subpage number APNDN:: .BLKA 1 ; Current appendix number(must be before CHPTN) CHPTN:: .BLKA 1 ; Current chapter number LEVNM:: .BLKA LEVSIZ+1 ; Current level numbers (must be after CHPTN) CHSK1:: .BLKB 1 ; Skip count 1 CHSK2:: .BLKB 1 ; Skip count 2 CHSK3:: .BLKB 1 ; Skip count 3 CHSP1:: .BLKB 1 ; Spacing count 1 CHSP2:: .BLKB 1 ; Spacing count 2 CHSP3:: .BLKB 1 ; Spacing count 3 LEVEL:: .BYTE 1 ; Current level number LINLV:: .BYTE 3 ; Lowest level with text-title run on CAPLV:: .BYTE 1 ; Highest all caps level MIXLV:: .BYTE 6 ; Highest level with first letter in caps NONLV:: .BYTE 7 ; Level - lowest without header number CENLV:: .BYTE 7 ; Level - lowest centered title BEGLV:: .BYTE 2 ; Level begin spacing ENDLV:: .BYTE 1 ; Level end spacing TPGLV:: .BYTE 8. ; Level test page SPCLV:: .BYTE 2 ; Spaces between number and title UNILV:: .BLKB 1 ; Unitary level number STLLV:: .BLKB 1 ; Autosubtitle level number OUTLV:: .BLKB 1 ; Levels enabled (0-6) TOCLV:: .BLKB 1 ; Levels enabled for TOC LIDLV:: .BLKB 1 ; Left level indent RIDLV:: .BLKB 1 ; Level indentation TIDLV:: .BLKB LEVSIZ ; Title indentation .even PARIND::.BLKA 1 ; Paragraph indentation PARSP:: .BLKA 1 ; Paragraph spacing count PARPT:: .BLKA 1 ; Paragraph page test count PARTT2::.BLKA 1 ; Paragraph post test count PARDFO: .BLKA 1 ; Paragraph deferred output PARDFT: .BLKA 1 ; Paragraph deferred top spacing PARDFB: .BLKA 1 ; Paragraph deferred bottom spacing PARDFH: .BLKA 1 ; Paragraph deferred hyphenation ; LINEC1&2 count lines as output, 3 when formatted LINEC1::.BLKA 1 ; Number of lines left to bottom active page LINEC2::.BLKA 1 ; Number of lines left (physical page) LINEC3::.BLKA 1 ; Number of free lines (counts saved data) FOTLN:: .BLKA 1 ; Number of lines permanent footnote LN3SAV::.BLKA 1 ; Saves old LINEC3 during text deferred TXDHED::.BLKA 1 ; Saves current text deferred header PFOTHD::.BLKA 1 ; Permanent footnote header CMADR:: .BLKA 5 ; Next expected command addresses LITSV:: .BLKA 1 ; SAVED FLAGS MASK ON LITERAL PROCESSING LSTKP:: .BLKA 1 ; CURRENT LIST STACK POINTER LSTK:: .BLKB *LS.SIZ ; LIST STACK (5 lists by SIZ saved bytes) TKPEND::.BLKB LS.SIZ ; End of list stack .even NOTLM:: .BLKA 1 ; NOTE SAVED LEFT MARGIN NOTRM:: .BLKA 1 ; NOTE SAVED RIGHT MARGIN NOTSV:: .BLKA 1 ; SAVED FLAG WORD ON NOTE PROCESSING EXSP1:: .BLKA 1 ; REAL SPACES/EXPANDABLE SPACE EXSP2:: .BLKA 1 ; COUNT TO NEXT EXTRA SPACE EXSP3:: .BLKA 1 ; -1=EXTRA SPACES TO LEFT 0=TO RIGHT EXSP4: .BLKA 1 ; Permanent EXSP3 EXMSP:: .BLKA 1 ; Extra micro spaces EXSTAT::.BLKB 1 ; I/O status EXLINE: .BLKB 1 ; Post line count .even CPOS:: .BLKA 1 ; CURRENT CHAR POSITION (set by VARSET) EQBOT:: .BLKA 1 ; Vertical size of equation denominator EQTOP:: .BLKA 1 ; Vertical size of equation numerator EQSTK:: .BLKA 62. ; Equation stack EQSEN:: ; End of equation stack FOTSV:: .BLKB SAVSZ ; FOOTNOTE SAVE PARAM TABLE PFTSV:: .blkb PFSIZ ; Permanent footnote save table .EVEN ESCTAB::.BLKB 18. ; Saves locked escape sequences .even NLPG:: .BLKA 1 ; MAX LINES THIS PAGE PNLPG:: .BLKA 1 ; Permanent max lines/page STSIZE=</16.>+</16.>+5 ; Number of status words saved USTAT:: .BLKA STSIZE ; User status block HDSTAT::.BLKA STSIZE ; header status block CHSTAT::.BLKA STSIZE ; chapter status block APSTAT::.BLKA STSIZE ; Appendix status block LVSTAT::.BLKA STSIZE ; level status block VAREND::.BLKA 1 ; end of variables NBASE: .BLKA 1 ; Base of numeric conversion .text ONPGTX: .ASCIZ / file: / ONLNTX: .ASCIZ /On input line / JUSRM1: .ASCIZ /RNO -- Can't justify line/ EQERTX: .ASCIZ /RNO -- Missing right braces (}) in equation/ TXDERR: .ASCIZ /RNO -- Deferred page overflow/ ;TXBOLD: .ASCIZ <33>/[1m/ ;TXUBOL: .ASCIZ <33>/[0m/ .even .code ; ; INPUT LINE ; LINUC:: CALL SHFUC ; Get input in Uppercase LIN:: CALL OUTAD ; GET OUTPUT BUFFER ADDRESS CALL LINBEG ; Begin line if necessary CALL GCIN ; Get input text CMPNEB R1,#LF,5$ ; NOT LINE FEED RETURN 5$: TSTNE BRCNT,7$ ; NO SPACES TO ALLOW HYPHENATION JMP 70$ ; Output 7$: CMPNEB LCH,#SPC,8$ ; Last char not space? JMP 60$ 8$: TST LINBK ; Line <= max length? BLT 9$ ; Line longer than max ? JMP 70$ ; No hyphenation 9$: TSTEQB $HYPSW,10$ ; Hyphenation ? JMP 60$ 10$: CMPB HYPCT,#2 ; Check previous hyphenation count BLT 11$ ; Not 3 hyphenated lines in a row ? JMP 60$ ; Prevent 3 in a row ; Inhibit hyphenation at bottom of page 11$: MOV LINEC3,R2 ; Check if at bottom of page SUB NSPNG,R2 ; Number of lines to test SUB EQBOT,R2 SUB EQTOP,R2 BLT 12$ ; Past the bottom ? SUB NSPNG,R2 SUB PARDFH,R2 ; Add deferred lines BGE 12$ ; Not at bottom of current page JMP 60$ ; Current line at bottom of current ? 12$: TSTEQB HYPSP,13$ ; No specified hyphenation ? CALL BKUP BR 50$ 13$: ; ********************************************************** .if df H$$PHN ; Autohyphenation ???? TSTEQB $AUHYP,131$ ; Autohyphenation ? JMP 60$ 131$: MOV LSTSP,R1 ; Address of last space SUB R1,LNINS ; Offset to last BGT 132$ ; Enough chars ? JMP 60$ 132$: CALL FNDBF ; SET POINTER TO IT MOV #TTBUF,R2 ; GET TEMPORARY BUFFER CLRB (R2)+ ; Chock beginning MOV #49.,R4 ; Maximum number of chars 14$: CALL GBYT ; GET CHARACTER BCS 17$ ; DONE BITNEB #^o140,R1,141$ ; Printable char? JMP 60$ 141$: BIC #^C<^o177>,R1 ; clear extra bits CMPEQB GCTABL(R1),#GC.LC,16$ ; lowercase ? CMPEQB GCTABL(R1),#GC.UC,15$ ; uppercase ? BITEQB CHTABL(R1),#CH.PNC,60$ ; Not legal punctuation ? BR 16$ ; Save punctuation 15$: ADD #^o40,R1 ; make it lowercase 16$: MOVB R1,(R2)+ ; SAVE CHAR SOB R4,14$ ; CONTINUE TILL DONE 17$: CLRB (R2)+ ; NULL FOR END OF STRING MOV #TTBUF+1,R0 ; BUFFER WITH HYPHENATION INFO CALL HYPHEN ; TRY TO HYPHENATE THE WORD BEQ 60$ ; No hyphenation ? MOV #TTBUF+1,R0 ADD LNINS,R0 ; POINTS TO END OF WORD 30$: TSTB -(R0) ; HYPHENATION? BMI 40$ ; YES BNE 30$ ; Not done ? BR 60$ ; NO HYPHENATION 40$: SUB #TTBUF+1,R0 ; Now is number of chars to transfer BLE 60$ ; No hyphenation set up ? MOVB R0,$GCEND ; NUMBER OF CHAR TO TRANSFER CALL BKUP ; BACKUP TO LAST SPACE CALL GCSPC ; AT BEGINNING INSERT SPACE CLRB $GCEND ; Regular return restored .endc ; ; *********************************************** 50$: CLRB HYPSP ; Clear hyphenation count MOV #MINUS,R1 ; INSERT HYPHEN CALL PUBYT ; Output it INCB HYPCT ; Count this hyphenation BR 70$ ; hyphenation done 60$: CALL BKUP ; BACKUP TO CORRECT LOCATION CLRB HYPCT ; Reset hyphenation count 70$: CALL OUTLIN ; OUTPUT LINE,JUSTIFIED IF FLAGS LINFIL: BITEQ #FILLF,F.1,110$ ; No fill ? 90$: CALL CCIN ; Get a char CMPEQB R1,#SPC,90$ ; Space ? CMPEQB R1,#CR,90$ ; Carriage return TSTNEB $KEEPT,95$ ; Keep leading tabs ? CMPEQB R1,#TAB,90$ ; Is char tab ? 95$: CMPNEB R1,#LF,100$ ; Not line feed RETURN ; Kill input line 100$: CALL BKSPI ; Backspace 1 110$: CALL LINBEG ; BEGIN A NEW LINE JMP LIN ; START NEXT LINE BKSPI:: MOV BUFAD,R0 ; current input header TSTEQ BF.FUL(R0),10$ ; at beginning? DEC BF.FUL(R0) ; Decrement index DEC BF.ADD(R0) ; Previous address INC BF.CNT(R0) ; Increment count 10$: RETURN ; ; ROUTINE TO BACKUP OVER LAST SPACE (INPUT + OUTPUT) ; BKUP:: CALL LSINRS ; Restore input stack CALL OUTAD ; OUTPUT BUFFER ADDRESS BKOUT:: TSTEQ BF.HED(R3),10$ ; No header ?? MOV LSTSP,R1 ; LAST SPACE ADDRESS CALL RSTBF ; GO BACK TO PREVIOUS POINT IN BUFFER MOV SPCH,R1 ; Current spacing char SUB LSPCH,R1 ; - previous = excess ADD R1,LINBK ; Restore remainder count MOV LSPCH,SPCH ; RESTORE CHAR COUNT MOV LESMSK,ESMSK ; Restore escape stack MOVB LUNLSW,$UNLSW ; Restore underline switch MOV CASSAV,CASE ; RESTORE PREVIOUS CASE MOV SPCNSV,SPCNT ; Restore previous space count MOVB LSCH,LCH ; RESTORE LAST CHAR BEFORE SPACE MOV LPHSP,PHSP ; Restore character spacing DEC BRCNT ; One fewer break 10$: RETURN ; ; The .NO SPACE COMMAND ; NOSPC:: CMPNEB LCH,#SPC,10$ ; Last char space ? CALL OUTAD BITEQ #FILLF,F.1,10$ ; Fill off ? JMP BKOUT ; Fill on ? 10$: RETURN ; ; ENDCM--END OF COMMAND ; ENDCM: CALL $FRCND ; FORCE TO LOGICAL END OF LINE CMPEQ $NFLSW,R1,LGO ; COMMAND FLAG NEXT CHARACTER? CMPEQ #SEMI,R1,LGO ; MORE TEXT ON LINE? CMPEQ R1,#CR,COMNT ; END OF LINE CMPEQ R1,#LF,LGO ; FINAL END OF LINE CALL CCIN ; Advance pointer for extra char. MOV #27.,R0 ; Error message CALL ILMSG KILCM:: CALL CCIN ; FORCE TO LOGICAL END OF LINE CMPEQ $NFLSW,R1,10$ ; COMMAND FLAG NEXT CHARACTER? CMPEQ #SEMI,R1,LGO ; MORE TEXT ON LINE? CMPEQ R1,#CR,COMNT ; END OF LINE CMPEQ R1,#LF,LGO ; FINAL END OF LINE BR KILCM 10$: CALL BKSPI ; Backspace over this char BR LGO ; Process next command ; ; SAVE CURRENT INPUT POINTERS IN BF.VSP ; TRCSAV::MOV R0,-(SP) ; Save regs MOV BUFAD,R0 ; Get buffer header CLR BF.HED(R0) ; Clear header MOV BF.FUL(R0),BF.VSP(R0) ; Save current index DEC BF.VSP(R0) ; Points to correct one now MOV (SP)+,R0 ; Restore RETURN ; ; END OF LINE PROCESSING ; COMNT:: ; Process comment lime CALL CCIN ; Get next char CMPNEB R1,#LF,COMNT ; Continue till end of line ; ; READ AND PROCESS NEXT LINE ; LGO:: MOV SPSAV,SP ; RELOAD STACK POINTER CALL CCIN ; READ INITIAL CHARACTER ON LINE TSTEQB EOFSW,20$ ; NOT END OF FILE? 5$: TSTNEB CSMOR,15$ ; Another input file pending ? CALL OUTNJ ; End current line BIC #FOTF,F.1 ; Kill any footnotes CALL OUTNJ ; End current line CALL TXDMP ; Dump out all text 10$: MOVB #-1,$HDRSW ; SET NO HEADER CLR TMARG ; No top margin CALL PAGEC ; FORCE A PAGE 15$: JMP ENDFIL ; END OF FILE 20$: CALL TRCSAV ; Save current for traceback CMPEQB R1,#LF,LGO ; FORMFEED ON INPUT? CMPNE $NFLSW,R1,25$ ; Not command flag ? JMP COMAN ; Execute command 25$: BITNE #IFFLG,F.1,COMNT; If flag on ?? BITEQ #LITFG,F.1,251$ ; Not processing literal ? JMP TEXT ; Literal 251$: BITNE #FILLF,F.1,26$ ; Filling from input file ? JMP 60$ 26$: TSTNEB $AUTSW,27$ ; Autoparagraph active ? JMP TEXT 27$: CMPEQB #CR,R1,40$ ; NULL LINE? CMPEQB #TAB,R1,30$ ; LEADING TAB? CMPEQB #SPC,R1,30$ ; Leading space ? TSTB $AUTSW ; Check type BGT 55$ ; Autotable ? BR TEXT ; Normal line 30$: CALL CCIN ; READ NEXT CHARACTER 35$: CMPEQB #SPC,R1,30$ ; SPACE? CMPEQB #TAB,R1,30$ ; TAB? CMPNEB #CR,R1,50$ ; NOT CARRIAGE RETURN? 40$: CALL CCIN ; BYPASS LINE FEED CALL CCIN ; READ NEXT CHARACTER TSTEQB EOFSW,45$ ; Not End of file? JMP LGO 45$: CALL TRCSAV ; Save current for traceback CMPEQB $NFLSW,R1,COMAN ; LEADING PERIOD? BR 35$ ; Now kill spaces 50$: TSTB $AUTSW ; Check type BGT TEXT ; Autotable ? 55$: CALL OUTNJ ; BREAK CURRENT LINE CALL PARTP ; PERFORM PARAGRAPH BREAK CALL LINBEG ; RESET LINE PARAMETERS BR TEXT ; PROCESS TEXT 60$: TSTNEB $KEEPL,TEXT ; Keep blank lines ? CMPNEB #CR,R1,TEXT ; Not null line ? JMP COMNT ; Discard null line TEXT:: CALL BKSPI ; BACKSPACE THE INPUT CALL LSINSV ; Save address of last space TEXTF:: CALL LINFIL ; Start input CALL OUTAD ; GET OUTPUT BUFFER TSTNEB $BRKSW,10$ ; Break at end of line TSTNEB $CENSW,10$ ; Centered text? TSTNEB $RIGSW,10$ ; Right justified text? BITEQ #FILLF,F.1,10$ ; Not Filling from input file? JMP LGO 10$: CALL OUTNBJ ; Output either not just, cent, or right just. JMP LGO ; End of input line COMAN: CALL COMND ; PARSE COMMAND MOV #ENDCM,-(SP) ; ASSUME NONBREAK COMMAND MOV (R3),-(SP) ; SET ADDRESS OF COMMAND ROUTINE MOVB (R2),-(SP) ; GET FLAG BYTE BITEQB #BRKF,(SP),100$ ; NOT BREAK COMMAND? CALL OUTNJ ; BREAK CURRENT LINE 100$: MOV #SW.DIS,R5 ; Set R5 to SW.DIS MOV #RCNO,R4 ; SET ADDRESS OF NUMBER CONVERSION ROUTINE BITEQB #RELF,(SP)+,120$ ;ABSOLUTE CONVERSION REQUIRED? MOV #RCNR,R4 ; SET ADDRESS OF RELATIVE CONVERSION ROUTINE 120$: JMP @(SP)+ ; DISPATCH TO COMMAND ROUTINE ; ; ERROR OUTPUT ; HLTER - Fatal internal error ; ILINP - Fatal error (r0 = error number) no return to caller ; ILCMA - Error during 2'nd pass (r0 = error number) no return ; ILCMB - Error during either pass (r0 = error number) no return ; ILCMC - Error second pass (R0 = message address ) with return to caller ; ERRRET: RETURN ILCMC:: .if df $PASS BITNEB #SW.DIS,$OUTSW,ERRRET ; First pass ? .endc CALL EROUT ; Output message BR ONLIN ; INDICATE WHAT PAGE HLTER:: MOV #9.,R0 ; Error message ILINP:: BIC #EROSW,$SWTCH ; Error output to terminal CALL ERMSG ; Output error message CALL ONLIN ; Output line number .if df $PASS BICB #SW.DIS,$OUTSW .endc JMP RUNOFF ; And begin again ILCMB:: MOV #KILCM,(SP) ; Finish up by finding next command BR ILCMM ILCM:: MOV #4,R0 ; Illegal command message ILCMA:: MOV #KILCM,(SP) ; Finish up by finding next command BR ILMSG ; After printing line and page number ILTXT: MOV #COMNT,(SP) ; FINISH UP SECTION ILMSG: .if df $PASS BITNEB #SW.DIS,$OUTSW,ERRRET ; First pass ? .endc ILCMM: CALL ERMSG ; Output error message unconditional ; ; Here we generate traceback through the substitutions ; ONLIN:: MOVB SUBSTK,R4 ; Get substitute stack 10$: MOV BUFADD(R4),R2 ; Now have substitute header CALL GETTBF ; Get temporary buffer into R3 MOV BF.FUL(R3),R1 ; Current position CMP R1,BF.HED(R3) ; Stopping point ? BLOS 20$ ; Past current location ? MOV R1,BF.HED(R3) ; Current index is stop 20$: MOV #TTBUF,R2 ; Temporary output buffer MOV BF.SPC(R3),R1 ; Start of substitution BEQ 42$ ; Starting point zero ? TSTEQ R4,42$ ; First ? CALL FNDBF 30$: CALL GBYT ; Get 1 byte BCC 31$ ; Not Done ? JMP 60$ ; Done 31$: BIC #^C<^o177>,R1 ; Strip extra bits BITEQ #^o140,R1,40$ ; Valid char ? MOVB R1,(R2)+ ; Move it CMP R2,#TTBUF+20. ; Too much ? BLO 30$ ; No ? 40$: MOVB #COLON,(R2)+ ; And colon 42$: MOVB #SBRA,(R2)+ ; Enclose in brakets MOV BF.HED(R3),R1 ; Get stopping point SUB BF.VSP(R3),R1 ; Subtract start BLT 45$ SUB #3.,R1 ; Subtract min size BGE 43$ SUB R1,BF.HED(R3) ; And new BF.HED BR 45$ 43$: SUB #50.,R1 ; Subtract 50 BLE 45$ ; Enough room left ? ADD R1,BF.VSP(R3) ; Move up starting point 45$: MOV BF.VSP(R3),R1 ; Get start of comm CALL FNDBF 50$: CALL GBYT ; And next substitute BLOS 60$ ; Done ? BIC #^C<^o177>,R1 ; Strip extra bits BITNE #^o140,R1,55$ ; Printable ? MOV #SPC,R1 ; Make it space 55$: MOVB R1,(R2)+ ; Save char CMPEQ BF.FUL(R3),BF.HED(R3),60$ ; At end ? CMP R2,#TTBUF+78. ; Too much ? BLO 50$ ; No ? 60$: MOVB #SKET,(R2)+ ; Enclose in brakets MOV #TTBUF,R0 ; Address to output SUB R0,R2 MOV R2,R1 CALL TTOUT ; Output traceback SUB #2,R4 ; Next subs. BLT 70$ ; The last ? JMP 10$ ; ; Print input line ; 70$: CALL TTINOU ; Type whole line for ident. ; ; Tracback through the input files ; ONPAG: BISB #^o20,$UNLSW ; No underlining MOV TRCBUF,-(SP) ; Traceback begin 1$: TSTEQ @(SP),30$ ; No traceback ? MOV #TTBF,R3 ; BUFFER FOR OUTPUT CALL CLRBF ; CLEAR BUFFER MOV #ONLNTX,R0 ; On line text string CALL PSTRZB ; MOVE IT TO BUFFER MOV (SP),R4 ; Get line MOV (R4)+,R0 ; Input Line number CALL DECTY ; Convert to number MOV #ONPGTX,R0 ; ON PAGE STRING CALL PSTRZB ; Into buffer 10$: MOVB (R4)+,R1 ; Get byte BEQ 20$ ; Done CALL PBYT BR 10$ 20$: MOV #TTBUF,R0 ; BUFFER ADDRESS MOV BF.FUL(R3),R1 ; SIZE OF STRING CALL TTOUT ; OUTPUT IT 30$: SUB #TRCLN,(SP) ; Next string ? CMP (SP),#TRCBUF ; At end ? BHI 1$ ; No BICB #^o20,$UNLSW ; underlining TST (SP)+ MOV #TTBUF,R0 ; Output blank line MOV #^o1,R1 ; 1 Char MOVB #SPC,(r0) JMP TTOUT ; ; Put converted page number into buffer ; PUTPAG:: CLR -(SP) ; stop for conversion routine MOVB #MINUS,$SEPR ; specify separator character TSTNEB $CHPSW,20$ ; no chapter print? MOV APNDN,R1 ; GET CURRENT APPENDIX LEVEL BEQ 10$ ; IF EQ NONE BIS APNDSP,R1 ; set display format MOV R1,-(SP) ; Save for conversion BR 20$ ; 10$: MOV CHPTN,R1 ; GET CURRENT CHAPTER NUMBER BEQ 20$ ; IF EQ NONE BIS CHPDSP,R1 ; set display format MOV R1,-(SP) ; Save for conversion 20$: MOV PAGENO,R1 BIS PAGDSP,R1 ; set display format MOV R1,-(SP) ; Save for conversion TSTEQB $SBPSW,40$ ; NO SUBPAGE? MOV SUBPGE,R1 ; SUB PAGE NUMBER BEQ 40$ ; none BIS SUBDSP,R1 ; set format MOV R1,-(SP) ; Save for conversion 40$: CALL PAGCV ; convert numbers RETURN ; ; ; CONVERTS PAGENUMBERS on stack terminated by null ; R3 = buffer header to recieve the final string ; Format NUMBER ; +100000 = Letters (upper case) ; +120000 = Letters (lower case) ; +140000 = Roman numeral (upper case) ; +160000 = Roman (lower case) ; +010000 = (upper case first letter) ; Roman numerals go from 0-2047 ; ; - sign appears after letters, before numbers. ; ex. 10-5 A-10 10A A-10B ; R2-R5 are preserved ; PAGCV:: MOV (SP),R0 ; save stack MOV SP,R1 ; To find base entry CLR (R1)+ ; clear old return address MOV R2,-(SP) ; Save R2 MOV R4,-(SP) ; And R4 MOV R0,-(SP) ; And return address 1$: TST (R1)+ ; base entry? BNE 1$ ; not yet ; now reverse stack between R1,R2 MOV SP,R2 ; current stack pointer 2$: MOV (R2),R0 ; save lower entry MOV -(R1),(R2)+ ; move upper to lower MOV R0,(R1) ; move lower to upper CMP R2,R1 ; not done? BLO 2$ ; yes TST (SP)+ ; unstack extra entry 3$: MOV (SP)+,R0 ; number? BNE 10$ ; YES 5$: MOV (SP)+,R2 ; Restore MOV (SP)+,R4 ; Restore RETURN 10$: MOV R0,R4 ; save status BIC #^C,R0 ; Clear extra bits BITNE #NM.ALP,R4,20$ ; Is it letter or Roman ? CALL DECTY ; convert number BR 50$ ; next! 20$: BITNE #NM.ROM,R4,70$ ; Roman? CLR -(SP) 30$: DEC R0 ; yes, decrement it DIV$ #26.,R0 ; Divide (R0=quotient) ADD #A,R1 ; convert to letter MOV R1,-(SP) ; save it TSTNE R0,30$ ; more? BR 110$ ; no, put into buffer 50$: MOV (SP)+,R2 ; end? BEQ 5$ ; yes BGT 60$ ; Number? BITNE #NM.ROM,R2,60$ ; Roman numeral? TST R4 ; last one letter? BGT 65$ ; no 60$: MOVB $SEPR,R1 ; output a separator CALL PBYT ; Output it 65$: MOV R2,R0 ; save char BR 10$ 70$: CLR -(SP) ; end of stack table MOV #RMTAB,R2 BR 85$ 80$: ADD #2,R2 ; Next numeral 85$: TSTEQ R0,110$ ; done yet? DIV$ #10.,R0 ; Divide (R0=quotient) TSTEQ R1,80$ ; none this letter? CMPEQ R1,#4,100$ ; reversed letters? BLT 90$ ; Less than 4 ? SUB #5,R1 ; Now is less 5 BEQ 88$ CMPNE R1,#4,86$ ; reversed letters? MOVB 2(R2),-(SP) ; ex. IX BR 101$ 86$: MOVB (R2),-(SP) ; save letters 87$: SOB R1,86$ ; till done 88$: MOVB 1(R2),-(SP) ; Save 5 char BR 80$ 90$: MOVB (R2),-(SP) ; save letters SOB R1,90$ ; till done BR 80$ 100$: MOVB 1(R2),-(SP) ; output next higher letter 101$: MOVB (R2),-(SP) ; and current one ex. 4 = IV BR 80$ 110$: MOVB (SP)+,R1 ; unstack numerals BNE 115$ ; Not done? JMP 50$ 115$: BITNE #NM.MC+NM.UC,R4,120$ ; Not upper case ? ADD #^o40,R1 ; make it lower 120$: CALL PBYT ; save in buffer BIC #NM.MC,R4 ; set lower? after first byte BR 110$ ; ; CONVERTS R0 TO NUMERIC STRING ; R3=BUFFER HEADER TO PUT STRING ; R2-R5 are preserved ; DECTY:: CLR -(SP) ; SET INDICATOR 10$: DIV$ #10.,R0 ; Divide (R0=quotient) ADD #^o60,R1 MOV R1,-(SP) ; SAVE RH DIGIT TSTNE R0,10$ ; CONTINUE IF NON ZERO 20$: MOVB (SP)+,R1 ; 1 DIGIT BEQ 30$ ; DONE CALL PBYT ; PUT INTO BUFFER BR 20$ ; CONTINUE TILL DONE 30$: RETURN ; ; ; BEGINS A LINE OR CONTINUES LINE AFTER COMMANDS BY SETTING FLAGS ; R3 is set to point to output buffer ; All other registers are destroyed ; ; LINFAK - Fake begin if line not in existance ; LINFAK::CALL OUTAD TSTNE BF.HED(R3),LINBEG; Line already begun ? CALL ENDBF ; Go to end of buffer MOV #BFHED-2,R2 ; NUMBER OF TIMES THRU CALL CBYT ; Spacing before MOV #HD.LIN,R1 ; Set it up as line CALL PBYT CLR R1 10$: CALL PBYT SOB R2,10$ CALL VARSET BR LSINSV RETURN LINBEG::CALL OUTAD ; GET OUTPUT ADDRESS MOV BF.HED(R3),R1 ; HEADER BYTE BEQ 20$ ; New line ?? CALL FNDBF ; get the location CALL GBYT ; get status byte TSTNEB $CBRSW,10$ ; NO CHANGE BAR NEEDED? BISB #HD.BAR,R1 ; SET CHANGE BAR BIT 10$: MOVB R1,@BF.ADD(R3); New status JMP ENDBF ; go to end of buffer 20$: CALL VARSET CALL ENDBF MOV BF.FUL(R3),R1 ; Start of header INC R1 ; Points to header MOV R1,BF.HED(R3) ; LAST HEADER ADDRESS MOV #BFHED-3,R2 ; NUMBER OF TIMES THRU CALL CBYT ; Spacing before TSTNEB $CBRSW,30$ ; NO CHANGE BAR NEEDED? BISB #HD.BAR,R1 ; SET CHANGE BAR BIT 30$: TSTEQB $VARSP,40$ ; No variable spacing BISB #HD.VAR,R1 40$: CALL PBYT ; Status MOVB NSPNG,R1 ; Line spacing after CALL PBYT CLR R1 ; NULL FOR HEADER 50$: CALL PBYT ; DEPOSIT PART OF HEADER SOB R2,50$ ; TILL DONE MOV ESMSK,R4 ; Escape sequences locked on BEQ 60$ ; None ? CALL ESCBEG ; Begin them 60$: MOV BF.FUL(R3),LSTSP;SET LAST SPACING CHARACTER BACK HERE CLR BF.SPC(R3) ; ; Save current input stack ; LSINSV::MOVB SUBSTK,R1 ; input stack MOV R1,LSSTK ; save old value 10$: MOV BUFADD(R1),R0 ; INPUT BUFFER MOV BF.FUL(R0),LSPIN(R1) ; LAST SPACE ON INPUT SUB #2,R1 ; next member BGE 10$ ; save more RETURN ; ; Set up variables at beginning of line ; VARSET::MOV RMARG,R0 ; COMPUTE REAL WIDTH OF LINE SUB LMARG,R0 ; AS DIFFERENCE OF MARGINS SUB INDCT,R0 ; MINUS INDENTING CALL CVHSP ; Get horizontal units MOV R1,LINBK ; STORE IN LINE-BREAK COUNT MOVB ULOCK,CASE ; Restore permanent case MOV CASE,CASSAV ; SAVE CASE CLR BRCNT ; no breaks yet this line CLR SPCNT ; INITIAL COUNTS OF SPACING CLR SPCNSV CLR SPCH ; AND NON-SPACING CHARS CLR LSPCH CLR ESCCNT ; NO ESCAPES PENDING CLR OVRCT ; NO BACKSPACE ABORTION CLR LCH ; CLEAR LAST CHARACTERs CLR LTAB ; Address of last tab char CLRB $TABPD ; Set no tab pending MOV ESMSK,LESMSK ; Current end of escape stack MOVB $UNLSW,LUNLSW ; Save underline switch MOV #1,CPOS ; CARRIAGE POSITION IS FAR LEFT RETURN ; ; Restore last input stack ; LSINRS::MOV R3,-(SP) ; Save regs MOV R4,-(SP) MOVB LSSTK,R4 ; stack at last space MOVB R4,SUBSTK ; restore previous substitute stack MOV BUFADD(R4),BUFAD; restore current buffer pointer 10$: MOV BUFADD(R4),R3 ; CURRENT BUFFER ADDRESS MOV LSPIN(R4),R1 ; LAST SPACE ADDRESS CALL FNDBF ; GO BACK TO PREVIOUS POINT IN BUFFER SUB #2,R4 ; more in stack? BGE 10$ ; yes MOV (SP)+,R4 ; Restore MOV (SP)+,R3 ; Restore RETURN ; ; RESET UNDERLINE BUFFER ; R0,R1 are destroyed ; ULBSET::MOV #UBUFF,R0 ; UNDERLIN BUFFER MOV #ULNSZ,R1 ; SIZE OF BUFFER MOV #SPC,R2 ; Char to transfer 10$: MOVB R2,(R0)+ ; PUT SPACE INTO IT SOB R1,10$ ; TILL FULL 20$: CLR ULNMAX CLRB $UNLRS MOV #1,CPOS RETURN ; ; ; RCNR -- RELATIVE DECIMAL CONVERSION ROUTINE ; INPUTS: ; R3=BASE VALUE TO BE AUGMENTED. ; ; OUTPUTS: ; CARRY = CLEAR if success ; SET if no number ; R3= R3 + input if input prefaced by + or - ; Unchanged If no input ; R1= 1 if number Prefaced by + ; R1= -1 if Prefaced by - ; V undefined ; ; RCNO--ABSOLUTE DECIMAL INPUT ROUTINE ; R3= 0 if no input ; Otherwise output is same as RCNR ; RCNO:: CLR R3 ; CLEAR ANSWER AC RCNR:: CALL FNDPAR ; skip spaces BCS 50$ ; null param MOV R2,-(SP) ; Save MOV R4,-(SP) MOV R5,-(SP) MOV R3,-(SP) ; Save CLR R3 ; Now start with clean slate CLR R5 ; Count number of chars converted CLR R4 ; AND SIGN FLAG CMPNE #PLUS,R1,10$ ; NOT PLUS SIGN? INC R4 ; SET PLUS SIGN PRESENT BR 20$ 10$: CMPNE R1,#MINUS,21$ ; NOT MINUS SIGN? DEC R4 ; SET NEGATE FLAG 20$: INC R5 ; Number present CALL CCINP ; READ ANOTHER CHARACTER 21$: CMPNEB GCTABL(R1),#GC.DIG,30$ ; NOT A DIGIT? ASL R3 ; MULTIPLY BY 10. MOV R3,-(SP) ; ASL R3 ; ASL R3 ; ADD (SP)+,R3 ; SUB #^o60,R1 ; SUBTRACT OUT CHARACTER BIAS ADD R1,R3 ; ADD IN DIGIT BR 20$ ; AND LOOP FOR MORE. 30$: CALL NEXPAR ; SKIP TO NEXT PARAM MOV R4,R1 ; Get sign BNE 36$ ; Sign ? TSTEQ R5,40$ ; No digits ? CLR (SP) ; Clear saved number 36$: BGE 40$ ; Plus sign ? NEG R3 ; NEGATE NUMBER 40$: ADD (SP)+,R3 ; Final value CLC TSTNE R5,45$ ; Number found ? SEC ; Set up status 45$: MOV (SP)+,R5 MOV (SP)+,R4 MOV (SP)+,R2 50$: RETURN ; ; ; Routine to skip to next param ; FNDPAR: CALL SKPSP ; SKip over tabs/spaces BCS 50$ ; No params CMPNEB R1,#PERCNT,40$ ; No indirect params ? MOVB SUBSTK,R0 ; Check stack level BEQ 40$ ; At lowest level ? MOV (SP)+,R1 ; And return address MOV SUBSTK,-(SP) ; Save status MOV BUFAD,-(SP) ; Save MOV #10$,-(SP) ; Return address MOV R1,-(SP) ; Co routine SUB #2,R0 ; Next stack entry MOVB R0,SUBSTK ; Save it MOV BUFADD(R0),BUFAD; INPUT BUFFER BR FNDPAR ; Now skip spaces 10$: MOV (SP)+,BUFAD ; Restore MOVB (SP)+,SUBSTK ; status 15$: MOV R0,-(SP) ; Save MOV R1,-(SP) BCC 20$ ; Carry clear ? CALL NEXPR1 MOV (SP)+,R1 ; Restore MOV (SP)+,R0 SEC RETURN 20$: CALL NEXPR1 MOV (SP)+,R1 ; Restore MOV (SP)+,R0 40$: CLC 50$: RETURN ; ; Routine to skip over spaces, tabs ; Stop at end of line, ;, and control flag ; Set CARRY if , or end of line. ; SKPSP:: CALL CCIN ; READ CHARACTER FROM COMMAND LINE CMPEQ R1,#CR,10$ ; LEADING CARRIAGE RETURN? CMPEQ $NFLSW,R1,10$ ; LEADING CONTROL CHARACTER? CMPEQ #SEMI,R1,10$ ; LEADING CHARACTER SEMICOLON? CMPEQ R1,#CMA,20$ ; LEADING COMMA? CMPEQ R1,#SPC,SKPSP ; SPACES AND TABS? CMPEQ R1,#TAB,SKPSP ; LEADING TAB? CLC ; done, no null params RETURN 10$: CALL BKSPI ; BACKUP TO SAVE CHAR. 20$: SEC ; null param RETURN ; ; SKIP OVER SPACE,BLANKS, AND 1 COMMA ONLY ; NEXPR1: CALL CCINP ; NEXT CHAR NEXPAR: TSTEQ R1,30$ ; Zero ? CMPEQ R1,#CMA,30$ ; COMMA? (discard and exit) CMPEQ R1,#SPC,NEXPR1 ; SPACE? CMPEQ R1,#TAB,NEXPR1 ; TAB? (discard all tabs + spaces) CALL BKSPI ; Keep char for next time around 30$: RETURN ; ; ; routine to get up to 3 char alphameric string ; String is in right justified RAD50 format ; C = SET IF No param ; R3 is unchanged if null param ; R3 = Result + Carry clear ; ; ; ALPGT2::MOV #^d26,NBASE ; Base BR ALPP ALPGT:: MOV #^o50,NBASE ALPP: CALL FNDPAR ; skip leading spaces BCS 50$ ; null param? CLR R3 ; initial number 20$: CMPB GCTABL(R1),#GC.LC ; letter? BGT 40$ ; no 30$: BIC #^C<^o37>,R1 ; convert letter to number MOV R1,-(SP) MUL$ NBASE,R3 ; Mult previous by base ADD (SP)+,R1 ; new total MOV R1,R3 CALL CCINP ; next BCC 20$ 40$: CALL NEXPAR ; set up for next param TSTEQ R3,50$ ; No Input ? CLC RETURN ; null param 50$: SEC ; no RETURN ; ; ; SUBROUTINE TO PARSE INPUT FOR LITERAL ; R0= address of literal ; R1= length of literal ; CARRY = CLEAR if success ; SET if none found ; Literal is in TTBUF maximum of 80 bytes! ; Literal is terminated by zero byte ; GETLIT:: CALL FNDPAR ; GET next BCS 50$ ; BAD, NO FILE SPEC CMPEQ R1,#APOSTR,10$ ; START OF LITERAL CMPNE R1,#QUOTES,40$ ; NOT START OFF LITERAL? 10$: MOV R2,-(SP) ; Save R2 MOV R1,-(SP) ; Save initial char MOV #TTBUF,R2 ; Buffer for literal CALL LSINSV ; Save this spot 20$: CALL CCINP ; NEXT CHAR BCS 35$ ; NO MORE CMP R2,#TTBUF+80. ; Check if at end of buffer BLO 25$ ; No ? MOV #51.,R0 ; Literal too long JMP ILCMA ; Yes kill this command 25$: CMPNEB R1,#TAB,26$ ; Not tab ? MOVB #SPC,R1 ; Make it space 26$: CMPEQB R1,(SP),30$ ; END OF LITERAL? CMPNE R1,#CR,32$ ; not end of buffer? CALL BKSPI ; backspace over carriage return BR 35$ ; Done 30$: CALL CCINP ; Get next char CMPNEB R1,(SP),35$ ; Not 2'nd delimiter ??? 32$: MOVB R1,(R2)+ ; Now save char BR 20$ ; And continue 35$: CLRB (R2) ; Now chock end of literal MOV R2,(SP) ; Save end of buffer CALL NEXPAR ; SKIP TO NEXT PARAM MOV (SP)+,R1 ; LAST CHAR IN LIT +1 ADDRESS MOV (SP)+,R2 ; Restore MOV #TTBUF,R0 ; Buffer for literal SUB R0,R1 ; NUMBER OF BYTES CLC ; OK! RETURN 40$: CALL BKSPI ; BACKUP 1 CHAR 50$: CLR R0 CLR R1 ; Setupt no literal SEC ; NOT OK RETURN ; ; $FRCND-FORCE TO LOGICAL END OF COMMAND ; $FRCND::CALL CCIN ; READ CHARACTER FROM FILE CMPEQ #SPC,R1,$FRCND ; SPACE? CMPEQ #TAB,R1,$FRCND ; TAB? CMPEQ #SEMI,R1,10$ ; SEMICOLON? CALL BKSPI ; BACKSPACE 1 CHAR 10$: RETURN ; ; ; Line output routine. two entry points ; OUTLIN - No break ; OUTNJ - Output with break ; OUTLIN::BITNE #FOTF!TEXF,F.1,10$ ; Footnote or Text ? TSTNEB $PAGNG,10$ ; No paging ? MOV PARDFT,R1 ; Get deferred count BEQ 10$ ; None ?? ADD EQTOP,R1 ADD EQBOT,R1 CMP R1,LINEC3 ; Check if deferred text BLE 10$ ; Not yet BIS #PARF,F.1 ; Set deferred lines 10$: MOVB #-1,TJFSW ; SET JUSTIFY FLAG COMB EXSP4 TSTNEB $BRKSW,OUTNJ0 ; Break end of line ? TSTNEB $CENSW,OUTNJ0 ; Centered/not justified ? TSTNEB $RIGSW,OUTNJ0 ; Not justify if right justified BITNE #JUSTF,F.1,OUTJ2 ;JUSTIFYING? BR OUTNBJ OUTNJ:: BIS #BRKF,F.1 ; Set for break OUTNBJ: CLRB HYPCT ; Clear hyphenation count OUTNJ0: CLRB TJFSW ; CLEAR JUSTIFY FLAG CLR EXSP4 ; CLEAR LEFT RIGHT SPACING OUTJ2: CLR EXSP2 CLR EXSP1 MOV #-1,EXMSP CLRB HYPSP ; Reset hyphenation spacing CALL OUTAD ; GET BUFF ADDRESS TSTNE BF.HED(R3),10$ ; Line exists ?? JMP OUTNJ3 ; Do not process output line 10$: TSTEQ @EQSTK,40$ ; Is equation not being formatted ? MOV #EQERTX,R0 ; Error message for equation CALL ILCMC MOV #EQSTK+$WORDL,EQSTK ; Reset equation stack MOV #SW.EDS,R0 ; Equation disable bits BICB R0,$TABSW ; ALLOW tabs BICB R0,$NOSPC ; expandable spaces BICB R0,$UFLSW+1 ; underlining BICB R0,$BRFSW+1 ; break flags BICB R0,$AUBRK ; autobreak BICB R0,$HYPSW ; hyphenation 40$: MOV ESMSK,R4 ; Escapes locked on BEQ 50$ ; None ? CALL ESCEND ; End the escape sequence 50$: TSTNEB TJFSW,51$ ; Justifying line? JMP OUTNJ1 51$: CLRB TJFSW ; IN CASE MOV RMARG,R0 ; YES. COMPUTE WHERE TO EXPAND THEM SUB LMARG,R0 ; SIZE OF LINE SUB INDCT,R0 ; .. SUB SPCH,R0 ; SUBTRACT NUMBER OF SPACING CHARS BEQ OUTNJ1 ; No justifacation needed ? MOV SPCNT,R1 ; NOW FIND HOW MANY MULT SPACES EACH SPACE IS BNE 60$ ; Spaces present to allow justif. ? MOV #JUSRM1,R0 ; Can't justify line message CALL ILCMC ; Output error message BR OUTNJ1 ; 60$: CLR EXSP1 ; Clear ; TSTEQB $VARSP,70$ ; No variable spacing ? ; TSTNEB VARESC,62$ ; Number of steps per space 62$: ADD R1,R0 ; ADD NUMBER OF SPACES DIV$ R1,R0 ; Divide (R0=quotient) MOV R0,EXSP1 ; MULTIPLIER FOR ALL SPACES TSTEQB $VARSP,70$ ; No variable spacing ? MOVB VARESC,R0 ; Number of steps per space BLT 70$ ; Bad value ? BEQ 65$ ; Zero ? MUL$ R1,R0 ; Mult R1 by R0 65$: DIV$ SPCNT,R1 ; Divide SPCNT into R0,R1 MOV R0,EXMSP ; Number of extra micro spaces 70$: TSTNEB EXSP4,80$ ; EXTRAS TO LEFT? NEG R1 ; RIGHT. GET SPACES BEFORE EXTRAS ADD SPCNT,R1 ; .. 80$: MOV R1,EXSP2 ; STORE FOR LATER OUTNJ1: CALL OUTAD ; GET BUFF ADDRESS MOV BF.HED(R3),R1 ; GET LIN HEADER DEC R1 ; Points to first byte CALL FNDBF ; Set to point to it CALL GBYT ; Get the line count ADD EQTOP,R1 ; Add on top of equation TSTNEB $PAGNG,10$ ; No paging ? TSTB $PFOOT ; Permanent footnote in progress ? Blt 5$ ; YES ? SUB R1,LINEC3 ; Account for extra lines 5$: ADD R1,BF.VSP(R3) ; And vertical spacing this buffer 10$: MOVB R1,@BF.ADD(R3) ; And save it CLR EQTOP ; No more pre spacing CALL GBYT ; Get status byte BISB #HD.LIN,R1 ; Set it as output line TSTNE SPCH,12$ ; Spacing chars ? BICB #HD.BAR,R1 ; No change bar 12$: MOVB R1,@BF.ADD(R3) ; Output line MOVB R1,EXSTAT ; Save status CALL GBYT ; Get post line count ADD EQBOT,R1 ; Get bottom spacing TSTNEB $PAGNG,20$ ; No paging ? TSTB $PFOOT ; Permanent footnote in progress ? BLT 15$ ; YES ? SUB R1,LINEC3 ; Account for extra lines 15$: ADD R1,BF.VSP(R3) ; Account for vertical spacing 20$: MOVB R1,@BF.ADD(R3) ; Save lines CLR EQBOT ; Clear bottom MOV LMARG,R2 ; GET LEFT MARGIN BICB #SW.TDS,$BRKSW ; Reset break switch TSTEQB $RIGSW,50$ ; Not right justify? BICB #SW.TDS,$RIGSW ; Reset temporary right justify MOV RMARG,R2 ; right margin SUB SPCH,R2 ; Now have indentation for right justify SUB INDCT,R2 ; Subtract indentation TSTNEB $RIGSW,55$ ; Still right justify ? BR 54$ 50$: ADD INDCT,R2 ; GET INDENTING IN CASE OF PARAGRAPH 54$: CLR INDCT ; (ONCE ONLY) 55$: TSTEQB $CENSW,60$ ; NO CENTERING? BICB #SW.TDS,$CENSW ; CLEAR TEMPORARY CENTERING MOV CMARG,R2 ; CENTERING MARGIN MOV SPCH,R0 ; NUMBER OF CHAR IN LINE ASR R0 ; DIVIDE BY 2 SUB R0,R2 ; NOW IS CHARS TO CENTER 60$: ADD EBSIZ2,R2 ; ADD ON CHANGE BAR SIZE BITEQB #HD.BAR,EXSTAT,70$ ; CHANGE BAR PENDING? DEC R2 ; 1 CHAR IS OUT SO STOP ITS SPACE 70$: MOV RIGSHI,R1 ; Right shift ADD EBSIZ1,R1 ; Plus bar spacing #1 CALL PBYT ; Output for initial spacing MOV R2,R1 ; Spacing after bar BGT 80$ ; Margin ok? CLR R1 ; No, make it 0 80$: CALL PBYT ; in buffer MOV EXSP1,R1 CALL PWRD ; in buffer MOV EXSP2,R1 CALL PWRD ; in buffer MOV EXSP4,R1 ; SAVED EXPANSIONS CALL PWRD ; in buffer MOV EXMSP,R1 ; Saved micro expansion CALL PWRD CALL ENDBF ; go back to end of buffer CALL CBYT ; Null at end of line CLR BF.HED(R3) ; No line available OUTNJ3: TSTEQB $PAGNG,1$ ; Paging ?? JMP 120$ ; No paging 1$: BITEQ #FOTF!TEXF,F.1,2$ ; No text or footnote ? JMP 100$ ; Text or footnote flags on 2$: BITEQ #BRKF,F.1,10$ ; No break this line ?? TST LINEC3 ; Check room this page BLT 10$ ; No room for deferred ? JMP 80$ ; Room for all deferred 10$: BITNE #PARF,F.1,11$ ; Deferred ? JMP 100$ ; No 11$: MOV PARDFT,R0 ; Get paragraph line deferral MOV PARDFB,R1 ; Get bottom deferred BITEQ #BRKF,F.1,70$ ; No break this line ?? CMPEQ R0,R1,20$ ; Same as bottom ? CMP R0,BF.VSP(R3) ; Deferr all ? BGT 30$ ; Yes 20$: MOV R1,R0 ; Deferred lines at bottom ADD LINEC3,R0 ; Subtract off number past endpage 30$: MOV R0,PARDFO ; Deferred lines BR 90$ 70$: ADD LINEC3,R1 ; Add to lines to test BLE 80$ ; Enough lines ? RETURN ; No continue 80$: CLR PARDFO 90$: BIC #PARF,F.1 ; No more deferred TSTEQB $FOTPD,95$ ; No footnote pending ADD FOTBF+BF.VSP,PARDFO ; Make room for it 95$: CALL OUTL0 ; Do the output CLR PARDFO BITEQ #BRKF,F.1,100$ ; Line not broken ? CLR PARDFB ; Yes, reset paragraph deferred CLR PARDFT ; CLR PARDFH 100$: BIC #BRKF,F.1 ; No break flag CALL TESTL BITNE #FOTF!TXDEF,F.1,140$ ; Footnote or deferred text? BITEQ #TEXF!PARF,F.1,120$ ; No text saved ?? TSTNEB $PAGBR,140$ ; not at top of page ?? 120$: BIC #BRKF!TEXF!PARF,F.1 ; Reset text flag JMP OUTL0 ; NO OUTPUT THE LINE 140$: RETURN ; ; ; DO ACTUAL OUTPUT TO PRINTER OF TEXT STRING ; OUTL0:: CLRB EXLINE CALL OUTAD ; GET HEADER ADDRESS CALL BEGBF ; SET TO TOP OF BUFFER OUTL1: MOVB EXLINE,R2 ; Get skip count CALL $SKIP0 ; Skip R2 lines CLRB EXLINE ; Clear skip CALL GBYT ; Get skip count BCC 5$ ; Not done JMP OUTL2 ; Done 5$: BIC #^C<^o377>,R1 ; Strip off extra byte MOV R1,R2 ; Now is skip count CALL GBYT ; Get status BITEQB #HD.TXD,R1,10$ ; Not end of text deferred buffer ? JMP TXDOU2 10$: MOVB R1,EXSTAT ; Save status BGE 15$ ; Normal line ?? TSTNEB $PAGNG,12$ ; No paging ? BITEQB #HD.FIG,R1,11$ ; Mandatory skip ? TSTNEB $PAGBR,11$ ; Page not already broken? ADD R2,LINEC3 ; Compensate for missing skip SUB R2,BF.VSP(R3) BR OUTL1 11$: TSTEQB $PAGBR,12$ ; Page already broken? CMP R2,LINEC1 ; Enough space left ?? BLE 12$ ; No ? SUB R2,BF.VSP(R3) ; Adjust vertical spacing MOV LINEC1,R2 ; MAKE IT MAX ADD R2,BF.VSP(R3) ; Adjust vertical spacing 12$: CALL $SKIP0 BR OUTL1 15$: BITNEB #HD.LIN,R1,16$ ; Output line ? TSTNE BF.HED(R3),13$ ; Header exists ? JMP HLTER ; No, this is fatal error 13$: JMP TXDOU3 16$: CALL GBYT ; Get post line count BIC #^C<^o377>,R1 ; Strip off extra byte MOVB R1,EXLINE ; Save it TSTNEB $PAGNG,20$ ; No paging ? ADD R2,R1 ; Total lines this one ADD PARDFO,R1 ; Add deferred lines CMP R1,LINEC1 ; Check if too big BLE 20$ ; Is it OK ? CLRB EXLINE MOV BF.FUL(R3),R1 ; Get current address DEC R1 BR TXDOU4 ; And save line 20$: CALL $SKIP0 ; Skip R2 lines CALL GBYT ; Get initial spacing BIC #^C<^o377>,R1 ; Strip off extra byte MOV R1,R2 ; CALL NSPAC ; Output n spaces BITEQB EXSTAT,#HD.BAR,30$ ; NO BAR? MOVB CHBAR,R1 ; NOPE CALL FOUT ; Output change bar INC CPOS ; Increment position counter 30$: CALL GBYT ; Spaces after bar BIC #^C<^o377>,R1 ; Strip off extra byte MOV R1,R2 ; MARGIN CALL NSPAC ; OUTPUT SPACES CALL GWRD ; Get spacing control parameters MOV R1,EXSP1 CALL GWRD MOV R1,EXSP2 CALL GWRD MOV R1,EXSP3 CALL GWRD MOV R1,EXMSP CALL CCOUT ; Output + format text BCS 40$ ; End of buffer ? CALL UNLOUT ; Output underlines JMP OUTL1 40$: CALL UNLOUT ; Output underlines MOVB EXLINE,R2 ; Get skip count CALL $SKIP0 ; Skip R2 lines ; ; END OF LINE, AND FOOTNOTE PROCESSING ; OUTL2: CLRB EXLINE ; Clear skip CLRB EXSTAT ; Clear status CLR EXSP1 ; Clear spacing controls CLR EXSP2 CLR EXSP3 MOV #-1,EXMSP BITEQ #FOTF,F.1,20$ ; No footnote in progress? CLRB $FOTPD ; CLEAR PENDING MOV PFOTHD,R1 ; Permanent footnote header BEQ 20$ ; Zero ? MOV FOTLN,BF.VSP(R3); Permanent footnote size JMP RSTBF ; Return to previous header 20$: JMP CLRBF ; CLEAR THE BUFFER ; ; Reshuffle buffer containing output lines ; TXDOU2: TSTEQB $PAGBR,5$ ; At top of page ? MOV R2,BF.VSP(R3) ; New vertical spacing BEQ 5$ CMP R2,LINEC3 ; Compare with available space BGT TXDOU3 ; Too big ? 5$: SUB R2,LINEC3 ; Subtract from LINEC3 JMP OUTL1 ; And do more TXDOU3: MOV BF.FUL(R3),R1 ; Get current index TXDOU4: SUB #2,R1 ; Backspace 2 BNE 1$ ; Not at beginning ? JMP ENDBF ; Go to end of buffer 1$: CALL FNDBF ; Move over to it MOV BF.HED(R3),R0 ; Get current header value BEQ 10$ ; None ? SUB R1,R0 ; Subtrac off offset MOV R0,BF.HED(R3) ; New header 10$: MOV R3,R2 ; Save address CALL GETTBF ; Get temporary header CALL BEGBF ; Start at beginning of buffer BITEQ #FOTF,F.1,20$ ; No footnote ? MOV PFOTHD,R1 ; Permanent footnote header BEQ 20$ ; None ? ADD FOTLN,BF.VSP(R2); Add on permanent lines to header TSTEQ BF.HED(R3),15$ ; No header ? ADD R1,BF.HED(R3) ; Add on permanent header 15$: CALL FNDBF 20$: CALL GBYT2 ; Get a byte BCS 30$ ; Done ? CALL PBYT ; Save it BR 20$ 30$: MOV BF.FUL(R3),R1 ; Reset buffer to end here MOV R2,R3 ; Switch to primary buffer JMP RSTBF ; ; Output underlines from buffer ; UNLOUT: MOV R3,-(SP) ; SAVE R3 TSTNEB $ULMSW,1$ ; Mode line ? JMP 50$ ; Backspace or none 1$: TSTNE ULNMAX,2$ ; Underlined chars in buffer ? JMP 40$ ; No underlines 2$: TSTB $ULMSW ; Now test mode BLT 10$ ; Line ? TSTNEB $PAGNG,5$ ; No paging SUB #LINSP,LINEC3 ; ACCOUNT FOR EXTRA LINE 5$: CALL CRLF ; SPACE TO NEXT LINE BR 20$ ; 10$: MOV #CR,R1 ; OUTPUT A CARRIAGE RETURN BITEQB #CRSW,$SWTCH,15$; No CRLF output? CALL FOUT ; 15$: CALL OUTPUT ; Start a new line 20$: MOVB #-1,$UNLRS ; Set up reset underline MOV #UBUFF,R3 ; GET UNDERLINE BUFFER MOV ULNMAX,R2 ; MAX CHAR 30$: MOVB (R3)+,R1 ; GET UNDERLINE CHAR BGT 36$ ; Not microspace ? BIC #^c<^o177>,R1 ; Strip extra bits MOV R1,-(SP) ; Save counter 31$: MOV #VARESC+1,R4 ; Microspace escape seq. DEC (SP) ; ANother time through ? BGE 32$ ; Yes ? TST (SP)+ ; Pop stacke BR 37$ 32$: MOVB (R4)+,R1 ; Get char BEQ 31$ ; Done yet ? CALL FOUT ; Output it BR 32$ 36$: CALL FOUT 37$: SOB R2,30$ ; TILL DONE 40$: TSTEQB $UNLRS,50$ ; No changes in underline buffer ? CALL ULBSET ; RESET UNDERLINE BUFFER POINTER 50$: MOV #1,CPOS CLRB $ULOSW ; No underlining yet MOV (SP)+,R3 ; RESTORE R3 RETURN ; ; OUTPUT deferred text ; TXDOUT::BITNE #TXDEF!FOTF,F.1,10$ ; Currently in deferred or footn. mode ? TSTEQ BF.VSP+TXDBF,10$; No data in buffer ? MOV F.1,-(SP) BIS #TXDEF!TEXF,F.1 ; Set up for deferred text CALL OUTL0 ; Output it MOV (SP)+,F.1 ; Restore 10$: RETURN ; ; END text deferred ; TXDEND::BITEQ #TXDEF,F.1,10$ ; Not text deferred ? CALL OUTAD ; Get address MOV TXDHED,R1 ; Get header CALL FNDBF ; Get it MOV BF.VSP(R3),R1 ; Spacing CALL PBYT ; Save it CALL ENDBF MOV #-1,BF.VSP(R3) ; Set up line size MOV LN3SAV,LINEC3 ; Restore saved size BIC #TXDEF!TEXF,F.1 ; No deferred text now 10$: BR TXDOUT ; Try to output text ; ; Dump all text ; TXDMP:: BITNE #TXDEF,F.1,1$ ; No text deferred ? BIC #TEXF,F.1 ; No text now 1$: CALL OUTNJ ; Dump current text CALL TXDEND CALL TXDOUT ; And any deferred 10$: TSTEQ BF.VSP+TXDBF,20$; No deferred text ? CALL BPAGE ; Output 1 page CALL OUTNJ ; Flush any normal text BR 10$ 20$: RETURN ; ; Subroutine to skip N text lines ; R1=skip count ; SKIPL is unconditional skip ; SKPLIF is conditional on if not at top of page ; SKPLIF::CALL MULSP ; Adjust spacing by the line spacing MOV R1,R2 ; Now is correct spacing BR SKPNIF SKIPL:: CALL MULSP ; Adjust spacing by the line spacing MOV R1,R2 ; Now is correct spacing BR SKIPN ; ; SUBROUTINE TO SKIP N LINES ON OUTPUT FILE ; R2 = NUMBER OF LINES TO SKIP ; bit 15 clear this is mandatory skip ; set no skip at top of page ; SKPNIF Skips if not at top of page ; SKPNIF::TSTNEB $PAGBR,10$ ; Not At top of page ? RETURN 10$: BIS #^o100000,R2 ; Set optional bit SKIPN:: MOV R2,R0 ; Skip in R0 CALL OUTAD ; GET BUFFER ADDRESS TSTEQ BF.HED(R3),1$ ; No header ?? JMP HLTER ; Yes, generate error message 1$: TSTEQB $PAGNG,2$ ; Paging ? JMP $SKIP0 ; No paging ?? 2$: BIC #^C<^o377>,R0 ; Strip extra bits BEQ SKRET ; YES DO NOT SKIP TSTB $PFOOT ; Permanent footnote BLT 40$ ; in progress ? 10$: CMP R0,LINEC3 ; LINE COUNT BLT 30$ ; Skip count not too many ? MOV LINEC3,R0 ; Skip to bottom BLE SKRET ; Bad skip? 20$: DECB $PAGPD ; New page pending 30$: SUB R0,LINEC3 ; Now line count 40$: ADD R0,BF.VSP(R3) ; Add to vertical spacing this buffer BIC #^o377,R2 ; Clear extra bits ADD R0,R2 ; And subs R0 BITEQ #FOTF!TEXF!PARF,F.1,$SKIP0 ; No footnote or deferred text? CALL ENDBF ; get the location MOVB R2,R1 ; Skip count CALL PBYT ; Save it MOV #HD.SKP,R1 ; Make this skip TST R2 ; Check if mandatory skip BGE 50$ ; Mandatory ? BISB #HD.FIG,R1 ; Set it as optional 50$: CALL PBYT ; Save skip header SKRET: RETURN $SKIP: BIC #^C<^o377>,R2 ; Strip extra bits BNE 10$ ; Any skip ?? RETURN 10$: TSTNEB $PAGNG,$SKIP1 ; No paging SUB R2,LINEC3 ; ADD LINES TO TOTAL BR $SKIP1 $SKIP0: BIC #^C<^o377>,R2 ; Strip extra bits BNE 10$ ; Any skip ?? RETURN 10$: TSTNEB $PAGNG,$SKIP1 ; No paging ? SUB R2,BF.VSP(R3) ; Number of lines this buffer $SKIP1: MOVB #-1,$PAGBR ; NOT AT TOP OF PAGE ; ; Perform half line skips ; R2=half line count ; BITEQ #1,R2,30$ ; No half lines required ? MOV R2,-(SP) ; save half line spacing TSTNEB $PAGNG,5$ ; No paging DEC LINEC1 ; Account for half lines DEC LINEC2 5$: MOV #DNMOV,R2 ; Get buffer to transfer 10$: MOVB (R2)+,R1 ; Get char BEQ 20$ ; Done ? CALL FOUT BR 10$ 20$: CALL OUTPUT ; Start a new line MOV (SP)+,R2 ; RESTORE NUMBER OF LINES 30$: BIC #1,R2 ; Clear half bit BLE 70$ ; No more to output 60$: CALL CRLF ; SPACE TO NEXT LINE SUB #LINSP,R2 ; Lines left BGT 60$ ; Not done ? 70$: RETURN ; ; ; ROUTINE TO OUTPUT SPACES TO FILE ; NSPAC:: DEC R2 ; If >0 more spaces to output BGE 10$ ; More ? RETURN ; none 10$: CALL CCSPC ; OUTPUT A SPACE BR NSPAC ; ; ; End of line output routine ; CRLF: BITEQB #CRSW,$SWTCH,10$ ; No CRLF output? MOVB #CR,R1 ; Get carriage return CALL FOUT ; Output it MOVB #LF,R1 ; And line feed CALL FOUT 10$: TSTNEB $PAGNG,20$ ; No paging ? SUB #LINSP,LINEC1 ; Counts active lines SUB #LINSP,LINEC2 ; And total lines 20$: JMP OUTPUT ; And end line ; ; SUBROUTINE PUTS CURRENT CHAR ADDRESS INTO R3 ; OUTAD:: BITNE #FOTF!TXDEF,F.1,10$ ; Deferred or footnote ? MOV #TX2BF,R3 ; NORMAL SECONDARY BUFFER RETURN ; 10$: BITEQ #FOTF,F.1,20$ ; NOT FOOTNOTE BUFFER? MOV #FOTBF,R3 ; GET FOOTNOTE BUFFER ADDRESS RETURN ; 20$: MOV #TXDBF,R3 ; Text deferred buffer RETURN ; ; ROUTINE TO SPACE TO TOP OF FORM ; FORM: CLRB $PAGPD ; No longer page pending ; ; Output FF or adjust to correct page height ; TSTNEB $PAGNG,40$ ; No paging TSTNEB $FIRPG,40$ ; First page? BITEQ #FFDSW,$SWTCH,10$ ;SPACING WITH LINE FEEDS? MOV #FF,R1 ; OUTPUT A FORMFEED CALL FOUT CALL OUTPUT ; Start a new line BR 40$ ; ADJUST COUNTS ; ; Go to end of page by adding lines ; 10$: MOV LPPG,R1 ; Number of lines/page BLE 40$ ; Too small ? MOV LINEC2,R2 ; Number of lines to skip 15$: BGT 20$ ; Skip correct ? BEQ 40$ ; none ? ADD R1,R2 ; Add on lines/page BR 15$ 20$: CALL $SKIP1 ; Skip over lines ; ; Now at end of page ; 40$: TSTNEB $OUTSW,50$ ; No output ?? CALL OPRWAT ; WAIT FOR OPERATOR TO POSITION FORMS ; ; Setup current page number ; 50$: CALL ULBSET ; Reset underline buffer in case MOVB $SBPSW,R0 ; Get subpage status BEQ 80$ BITEQ #SW.DIS,R0,70$ ; No subpage requested ? BISB #SW.TDS,$SBPSW ; Set keep bit TSTEQB $SETPG,60$ ; Page reset ? MOV PAGNX,R0 ; Keep page requested MOV R0,PAGENO ; Current page number INC R0 MOV R0,PAGNX ; Next page 60$: MOVB SUBNX,SUBPGE ; set to current subpage INCB SUBNX ; yes increment it BNE 90$ ; Non zero? INCB SUBNX ; No, make it 1 BR 90$ 70$: MOVB #1,SUBNX ; Next subpage number CLRB $SBPSW ; No subpage CLRB SUBPGE ; No subpage 80$: MOV PAGNX,R0 ; now current page number MOV R0,PAGENO INC R0 ; increment next page number MOV R0,PAGNX ; Save new page number ; ; Test if this page output ; 90$: TSTNE PAGENO,100$ ; Page number ok ? INC PAGENO ; No make it 1 100$: CLRB $SETPG BISB #SW.TDS,$OUTSW ; Set for no output CMP PAGENO,LOWPAG ; ONLY PRINT IN THE SELECTED PAGE BLO 150$ ; RANGE CMP CHPTN,LOWCHP ; chapter # too small? BLO 150$ ; yes CMP APNDN,LOWAPN ; appendix too small? BLO 150$ ; yes BITNEB #SW.DIS,$OUTSW,150$; First pass of 2 ? CMP PAGENO,HGHPAG ; page number too big? BHI 110$ ; yes CMP CHPTN,HGHCHP ; too big? BHI 110$ ; yes CMP APNDN,HGHAPN ; appendix too big? BLOS 120$ ; No ? 110$: JMP ENDFIL ; Terminate file 120$: BITNE #1,PAGENO,130$ ; Current page number odd ? BITNE #EVESW,$SWTCH,150$; Even pages off ? BR 140$ 130$: BITNE #ODDSW,$SWTCH,150$; Odd pages off ? 140$: BICB #SW.TDS,$OUTSW ; Set output on ; ; Set up params next page ; 150$: MOVB NXLAY,$LAYOU ; Current layout is now Next layout MOVB PRLAY,NXLAY ; Next is permanent layout MOV NXEPSP,$EOPSP ; Next end-of-page spacing MOV PREPSP,NXEPSP ; Permanent eop spacing MOV NLPG,LINEC1 ; Active lines this page SUB $EOPSP,LINEC1 ; Subtract off bottom lines MOV LINEC1,LINEC3 ; Potential lines per page TSTEQB $FOTPD,160$ ; Footnote not pending ? SUB FOTBF+BF.VSP,LINEC3 ; Subtract off header size 160$: MOV LPPG,LINEC2 ; Number of actual lines remaining this page RETURN ; ; Routine to convert vetical spacing to appropriate number ; CVSP:: TSTEQB $HSPSW,10$ ; Half spacing ? ASL R3 ; Convert to half space count 10$: RETURN ; ; CVHSP - Convert R0 to horizontal spacing units in R0,R1 ; CVHSP:: MUL$ HUNIT,R0 ; Get correct units RETURN ; ; Converts horiz spacing into spaces + micro spaces ; INPUT: R0 = spacing ; OUTPUT: R1 = micro spaces, R0 = spaces ; CVHSP2::DIV$ HUNIT,R0 ; Get spaces in R0,Micros in R1 RETURN ; ; Find actual adjusted lines ; R1=# of text lines ; R0,R1=hi,low order result ; MULSP:: MOV NSPNG,R0 ; Get line spacing MUL$ R1,R0 ; Mult R1 by R0 RETURN ; ; Test if room for lines of text ; TESTT:: CALL MULSP ; Convert to actual spacing BR TESTP ; ; Test if enough room for 1 more line, and if not break page ; TESTL: CLR R1 ; Check if no more room ; ; R1 = number of lines requested, check if break page? ; TESTP:: TSTNEB $PAGNG,10$ TSTB $PFOOT ; Permanent footnote in progress? BLT 10$ ; Yes ? CMP R1,LINEC3 ; COMPARE TO LENGTH BLE 10$ ; Enough lines ? MOV R1,-(SP) ; Save R1 CALL BPAGE MOV (SP)+,R1 ; Restore TSTEQB $PAGBR,20$ ; Currently at top of page ? BR TESTP ; START A NEW PAGE 10$: SEC ; NO PAGE BROKEN RETURN ; 20$: CLC ; Page broken RETURN ; ; SUBPAGE command ; TPAGE:: BISB #SW.DIS,$SBPSW ; Set subpage flag BR BPAGE ; ; Reset to page # 0 and begin new page ; PAGRST:: TSTNEB $CHPSW,PAGEC ; Not chapter oriented? MOV #1,PAGNX ; Next page number is 1 ; ; END SUBPAGE command ; PAGEC:: BICB #SW.DIS,$SBPSW ; CLEAR SUBPAGE FLAG BR BPAGE ; ; PAGE command (new page only if not already at top-of-page) ; CPAGE:: TSTNEB $PAGBR,BPAGE ; Page not already broken? CLC ; Signify page broken ; ; BREAK COMMAND ; BREAK:: RETURN ; ; Start new page routine ; BPAGE:: MOV F.1,-(SP) ; Save 1$: MOV (SP),F.1 ; Get flags BITEQ #TXDEF,F.1,5$ ; No text deferred ? MOV #TXDERR,R0 ; Error message CALL EROUT ; Text deferred is illegal here CALL TXDEND ; End the deferred buffer 5$: TSTNEB $FIRPG,30$ ; First page of document ?? BITEQ #FOTF,F.1,10$ ; No footnote in progress? CALL OUTL0 ; Do footnote output MOVB #-1,$FOTPD ; Reset pending in case it is reset BR 30$ 10$: TSTEQB $FOTPD,30$ ; NO FOOTNOTE PENDING? MOV LINEC3,R2 ; LINES LEFT BLE 20$ ; NONE CALL $SKIP ; SKIP THEM 20$: BIS #FOTF,F.1 ; SET FLAG CALL OUTL0 ; OUTPUT IT BIC #FOTF,F.1 ; Now set no footnote 30$: CALL BPAG2 ; Actually output page header BICB #SW.TDS,$HDRSW ; Reset temporary header disable CLRB $FIRPG ; Indicates not first page of document CLRB $ULOSW ; No underlining CLRB $PAGBR ; INDICATES AT TOP OF PAGE TSTNEB $SBPSW,100$ ; Currently in subpage ? CALL TXDOUT ; Check for deferred text output 100$: SUB TX2BF+BF.VSP,LINEC3 ; Subtract off saved lines BGE 120$ ; Is it OK ? BITEQ #TEXF,F.1,120$ ; No text ? TSTEQB $PAGBR,120$ ; No text on page ? JMP 1$ 120$: BIC #PARF,(SP) ; No paragraph deferred CLR PARDFO BITNE #FOTF,(SP),130$ ; Footnote in progress ? CALL OUTL0 ; Dump rest of paragraph 130$: MOV (SP)+,F.1 ; Get flags 140$: CLC ; page break indicated RETURN ; ; Output page header ; BPAG2: CALL VARSAV ; Save all necessary variables CALL STKSAV ; Save input stack MOV #NFLAGS,R1 ; Number of flags MOV #$AFLSW,R0 ; Address of table 5$: BIC #FL.LIT!FL.ALL,(R0)+; Clear literal/all flags disable SOB R1,5$ ; For all flags BIC #JUSTF!FOTF!TEXF!TXDEF!PARF,F.1 ; Remove inconvenient flags BIS #FILLF,F.1 ; Set fill ADD $EOPSP,LINEC1 ; restore bottom lines MOVB #SUBLEV*4,SUBSTK+1 ; Set up for extra levels of nesting MOV #HDSTAT,R2 ; Header status buffer CALL RSTAT ; Get header status MOV #1,PHSP ; Set permanent horiz spacing CLR INDCT ; Clear indentation MOV PRMRG,RMARG ; Use permanent margins MOV PLMRG,LMARG ; Use permanent margins BISB #SW.TDS,$UNLSW ; Set underlining off CLRB $ULOSW ; No underlining of headers! TSTNEB $FIRPG,30$ ; First page? TSTNEB $PAGNG,30$ ; No paging ? BITEQB #LAY.NB,$LAYOU,30$ ; Not number at bottom of page? MOV LINEC1,R2 ; Lines remaining this page SUB #LINSP,R2 ; Compensate for number to print BLE 10$ ; None? CALL $SKIP ; Skip em 10$: CALL HDMRG ; Set up left margin CALL HDPAG ; Get page to output MOV #LINSP,R2 ; Skip 1 line CALL $SKIP ; To end number at bottom of page 30$: CALL FORM ; OUTPUT FORMFEEDS OR LINEFEEDS MOV TMARG,R2 ; LINES TO SKIP BLE 40$ ; NONE CALL $SKIP ; SKIP N LINES 40$: TSTNEB $HDRSW,90$ ; NO HEADERS TO BE PRINTED? TSTNEB $PAGNG,90$ ; No paging ? CALL HDMRG ; Set up left margin TSTNEB $NTITL,50$ ; no title? MOV #TTLBF,R3 ; HEADER BUFFER CALL CENTIT ; Center title if necessary 50$: BITNEB #LAY.NB,$LAYOU,60$ ; Page number at bottom? CALL HDPAG ; Get page number 60$: MOV #LINSP,R2 ; LINES TO SKIP CALL $SKIP ; DO IT TSTNEB $NTITL,70$ ; no title? CALL HDMRG ; Set up margins MOV #STLBF,R3 ; OUTPUT THE SUBTITLE, IF ANY CALL CENTIT ; Center the subtitle? 70$: MOV HSPAC,R2 ; LINES TO SKIP BGT 80$ MOV #LINSP,R2 ; Only 1 skip 80$: CALL $SKIP ; DO IT 90$: RETURN ; ; Get margin and space over to it ; HDMRG: CLR ESMSK ; No escape seq yet. CALL VARSET MOV EBSIZ1,R2 ; SPACE FOR CHANGE BAR OFFSET ADD EBSIZ2,R2 ADD RIGSHI,R2 ; ADD ON RIGHT SHIFT ADD PLMRG,R2 ; Add on Permanent left margin CALL NSPAC ; SPACE TO MARGIN RETURN ; ; ; Subroutine to form title/subtitle for output ; CENTIT: CALL BEGBF ; Start at beginning of buffer MOV CASE,-(SP) ; Save case CLR -(SP) ; Offset to account for CMPNE R3,#TTLBF,1$ ; Not title buffer BIS TTLCAS,CASE ; Set up case BITNEB #LAY.NB,$LAYOU,2$ ; Page number at bottom? MOV #10.,R0 ; Make room for it CALL CVHSP ; Convert horizontal units MOV R1,(SP) ; Save SUB R1,LINBK ; For page number 1$: BIS STLCAS,CASE ; Set subtitle case 2$: MOV R3,R2 ; Set up to get data as input MOV #TTBF,R3 ; Will be output buffer CALL CLRBF CALL TMPINB ; Set up temporary input BISB #SW.HDR,$IFLSW+1; Prevent indexing BISB #SW.HDR,$TABSW ; Prevent tabs BISB #SW.DIS,$CONT ; Prevent continuation CALL GCIN ; Get input BICB #SW.HDR,$TABSW ; Allow tabs BICB #SW.HDR,$IFLSW+1; Allow indexing TST LINBK ; Check chars count left CALL POPINS ADD (SP)+,LINBK ; For page number MOV (SP)+,CASE ; Restore MOV LINBK,R2 ; get remaining char count BLE HDPRN ; None to do BITNEB #LAY.CT,$LAYOU,10$ ; Center title? BITNEB #LAY.RT,$LAYOU,HDPRNS ; Right title BITEQB #LAY.OT,$LAYOU,HDPRN ; No odd even layout BITEQB #1,PAGENO,HDPRN ; Not odd page number? BR HDPRNS ; Shift to right justify 10$: ASR R2 HDPRNS: CALL NSPAC ; Space over to margin HDPRN: MOV ESMSK,R4 ; Get escape mask CALL ESCEND ; Terminate escapes CLR ESMSK ; No escape seq MOV #1,PHSP ; Reset permanent spacing BISB #SW.TDS,$UNLSW ; Set underlining off CALL PSTRPA JMP UNLOUT ; ; Set up page number to print ; HDPAG: TSTEQB $NUMSW,10$ ; Page number? RETURN 10$: CALL SETINS ; Get input TSTNEB $PAGSW,20$ ; OUTPUT 'PAGE'? MOV #PAGHD,R0 ; PAGE HEADER CALL PSTRZB ; MOVE IT TO BUFFER 20$: CALL PUTPAG ; PUT PAGE INTO BUFFER ALSO MOV #PAGH2,R0 ; And second header CALL PSTRZB ; MOVE IT TO BUFFER MOV #LF,R1 ; End input CALL PBYT MOV BF.SPC(r3),R1 ; Get starting loc CALL FNDBF MOV #TTBF,R3 ; GET TEMPORARY BUFFER CALL CLRBF ; CLEAR IT CALL GCIN CALL POPINS ; No more input MOV LINBK,R2 ; Number of chars left BITNEB #LAY.CP,$LAYOU,40$ ; Centered page number? BITNEB #LAY.LP,$LAYOU,30$ ; left page ? BITEQB #LAY.OP,$LAYOU,50$ ; No odd even layout BITNEB #1,PAGENO,50$ ; Odd page number? 30$: JMP HDPRN 40$: ASR R2 ; Center it 50$: BR HDPRNS ; Now print result RETURN ; ; Output headers ; HDOUT:: TSTEQB (R2),20$ ; No header to output CALL TMPIN ; Set up temporary input buffer BISB #SW.HDR,$IFLSW+1; Prevent indexing BISB #SW.HDR,$TABSW ; Prevent tabs MOV F.1,-(SP) ; Save BIC #FILLF,F.1 ; No fill from literal CALL GCIN ; Get input MOV (SP)+,F.1 BICB #SW.HDR,$TABSW ; Allow tabs BICB #SW.HDR,$IFLSW+1; Allow indexing CALL POPINS ; Pop the stack 20$: RETURN ; ; SSTAT saves status (flags,switches,caps mode etc.) ; RSTAT restores status ; R2=address of STSIZE word block to contain status ; R0,R1 destroyed ; SSTATS save status on stack ; R0-R2 destroyed SSTATS::MOV (SP),R0 ; Return address SUB #STSIZE*2,SP ; Set up stack MOV R0,(SP) ; Set up return MOV SP,R2 ; Where to save status TST (R2)+ ; Beginning of table CALL SSTAT ; Store status CALL @(sp)+ ; Come back later MOV SP,R2 ; Restore status CALL RSTAT MOV R2,SP ; Restore stack RETURN SSTAT:: MOV R3,-(SP) ; Save regs MOV #switS,R1 ; swit address MOV #NswitS,R3 ; Size of table MOV R3,(R2)+ ; start of status MOV R3,-(SP) ; Save on stack 1$: CLR (R2) ; Set up this entry MOV #1,R0 MOV (SP),R3 CMP R3,#16. ; Check if too big BLE 10$ MOV #16.,R3 ; Max count 10$: BITB #SW.DIS,(R1)+ ; Check swit BEQ 20$ ; No bit ? BIS R0,(R2) ; Set bit in mask 20$: ASL R0 ; Next mask SOB R3,10$ TST (R2)+ ; Next entry in table SUB #16.,(SP) ; Decrement BGT 1$ MOV #$AFLSW,R1 ; Flags address MOV #NFLAGS,(SP) ; Number of flags 40$: CLR (R2) ; Set up this entry MOV #1,R0 MOV (SP),R3 ; Get count CMP R3,#16. ; Check size BLE 50$ ; Ok ? MOV #16.,R3 ; Set to 16 50$: BITEQ #FL.ALL,(R1)+,60$ ; No bit set ? BIS R0,(R2) ; Set bit in mask 60$: ASL R0 ; Next mask SOB R3,50$ TST (R2)+ ; Next entry in table SUB #16.,(SP) ; More ? BGT 40$ ; yes ? TST (SP)+ MOV F.1,(R2)+ ; Save status MOV CASE,(R2)+ ; And case MOV (SP)+,R3 RETURN RSTAT:: MOV R3,-(SP) ; Save regs MOV #switS,R1 ; swit address MOV #NswitS,R3 ; Size of table CMPNE R3,(R2)+,80$ ; Not correct status MOV R3,-(SP) ; Number of entries 1$: MOV (SP),R3 MOV (r2)+,R0 CMP R3,#16. ; Check if too big BLE 10$ MOV #16.,R3 ; Max count 10$: ASR R0 ; Get bit BCC 20$ ; No bit ? BISB #SW.DIS,(R1)+ ; Set status bit BR 25$ 20$: BICB #SW.DIS,(R1)+ 25$: SOB R3,10$ SUB #16.,(SP) ; Current count BGT 1$ ; Ok ? MOV #$AFLSW,R1 ; swit address MOV #NFLAGS,(SP) ; Number of flags 40$: MOV (r2)+,R0 MOV (SP),R3 ; Get count CMP R3,#16. ; Check size BLE 50$ ; Ok ? MOV #16.,R3 ; Set to 16 50$: ASR R0 ; Get bit BCC 54$ ; No bit ? BIS #FL.ALL,(R1)+ ; Set status bit BR 60$ 54$: BIC #FL.ALL,(R1)+ 60$: SOB R3,50$ SUB #16.,(SP) ; More ? BGT 40$ ; yes ? TST (SP)+ ; Pop temporary MOV (R2)+,F.1 ; restore status MOV (R2)+,CASE ; And case 80$: MOV (SP)+,R3 ; Restore RETURN ; ; This saves all necessary variables ; R0,R1,R2 are destroyed ; VARSAV::MOV #FLGBEG,R0 ; Variables to save MOV #/2,R1 ; Number of variables MOV (SP)+,R2 ; Return address 10$: MOV (R0)+,-(SP) ; Save the variables SOB R1,10$ ; Till done MOV R0,-(SP) MOV R2,-(SP) CALL @(SP)+ ; Back to main prog MOV (SP)+,R0 ; Variables to save MOV #/2,R1 ; Number of variables 20$: MOV (SP)+,-(R0) ; Save the variables SOB R1,20$ ; Till done RETURN ; ; Save input stack ; STKSAV: MOV (SP)+,R0 ; Return address MOV SUBSTK,-(SP) ; Save status MOV BUFAD,-(SP) ; Save MOV R0,-(SP) ; Return address CALL @(SP)+ ; Back to main prog MOV (SP)+,BUFAD ; Restore MOV (SP)+,SUBSTK ; status RETURN ; ; Do paragraphing ; PARTP:: MOV PARSP,R1 ; Paragraph line spacing CALL SKPLIF ; Skip if not at top of page MOV PARIND,INDCT ; SET INDENTATION PART0:: MOV PARPT,R1 ; Get test page count PART1:: CALL MULSP ; Get total lines MOV R1,R5 ; Top count saved MOV PARTT2,R1 ; Deferred lines CALL MULSP ; Calculate deferred line spacing MOV R1,R4 ; Save it PARTS:: BITNE #FOTF!TEXF,F.1,10$ ; No allowed during footnote or text TSTNEB $PAGNG,10$ ; Not allowed during no paging MOV R4,R1 ; Post count CMP R1,NSPNG ; Is it trivial BLE 5$ ; Yes ? MOV R1,PARDFB ; Save line spacing MOV R1,PARDFT ; Save line spacing SUB NSPNG,R1 ; Subtract 1 line MOV R1,PARDFH ; Save line spacing CMP R5,NSPNG ; Top trivial ? BLE 5$ ; Yes ADD R5,R4 ; Top + bottom CMP R4,LINEC3 ; Enough room ? BLE 5$ ; Yes ? MOV R4,PARDFT ; Set separate top MOV LINEC3,R1 ; Number of lines left SUB R5,R1 MOV R1,PARDFH ; Set hyphenation inhibit 5$: MOV R5,R1 ; Get final value TSTEQB $PAGBR,10$ ; Already at top of page? JMP TESTP ; TEST AND OUTPUT PAGE IF NECESSARY 10$: RETURN ; ; ; START OF RUNOFF ; START: CALL $START ; Set up to receive commands RUNOFF::MOV SPSAV,SP ; Reset stack CALL INITL ; INITIALIZE VARIABLES JMP RESTRT ; Continue .END START