	.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*<CH.HD1+1>	; Level headers
APNM2::	.BLKB	CH.HD2+1	; Appendix trailing text
CHPM2::	.BLKB	CH.HD2+1	; Chapter trailing text
	.blkb	LEVSIZ*<CH.HD2+1>	; 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	<LISSIZ>*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=<<NFLAGS-1>/16.>+<<NSWITS-1>/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<NM.MSK>,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	#<SAVEND-FLGBEG>/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	#<SAVEND-FLGBEG>/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
