PROCEDURE	<RUNOFF, Database + support routines>,020012
;+
; Copyright (c) 1976
; Digital Equipment Corporation, Maynard, Mass.
;
; This software is furnished under  a license for use only  on  a
; single computer system and may be  copied only with  the inclu-
; sion of  the  above  copyright notice.  This software,  or  any
; other copies thereof, may not be  provided  or  otherwise  made
; available to any other person except  for  use  on  such system
; and to  one who agrees  to  these license  terms.  Title to and
; ownership of the software shall at all times remain in DEC.
;
; The information in this software  is  subject to change without
; notice and should not be construed  as  a commitment by Digital
; Equipment Corporation.
;
; DEC assumes no responsibility for the use or reliability of its
; software on equipment which is not supplied by DEC.
;
; Written: 01-Jun-72, -1.0.0-, L. Wade
;
; Modified: 12-Jan-80, -2.0.0-, Henry R. Tumblin
;	Produced Duke supported version
;
; Verified: 12-Jan-80, -2.0.0-, Henry R. Tumblin
	.IF	DF	A$$RAP
;
; Modified: 26-Aug-80, -2.0.1-, John D. Leonard
;	Added sub/super spacing and fixed backspace justification error.
;
; Modified: 05-Sep-80, -2.0.2-, John D. Leonard
;	Fixed bug in footnote save buffer pointer FOOTWB
;
; Modified: 12-Sep-80, -2.0.3-, John D. Leonard
;	Added support for second character set
;
; Modified: 30-Sep-80, -2.0.4-, John D. Leonard
;	Fixed page counting, modified subpage and fixed figure page skips
;
; Modified: 02-Sep-80, -2.0.5-, John D. Leonard
;	Converted to allow 1/8 line spacing on Diablo
;
; Modified: 06-Oct-80, -2.0.6-, John D. Leonard
;	Removed initial skip after formfeed. Added Top Margin (.TM)
;	facility. Set NLHDR global for # of lines in header.
;	Adjusted position of PAGE in heading, didn't allow for left margin.
;	Permit 'PAGE ' to be omitted
;
; Modified: 07-Nov-80, -2.0.7-, John D. Leonard
;	Added HFIN1 buffer for .SUBD/SUB substitution on input lines
;
; Modified: 14-Nov-80, -2.0.8-, John D. Leonard
;	Modified for half-space support in equation mode
;
; Modified: 20-Nov-80, -2.0.9-, John D. Leonard
;	Added half-spacing in text and use halfspacing for justification
;
; Modified: 04-Dec-80, -2.0.10-, John D. Leonard
;	Added 10/12 pitch margin defaults and /PITCH:n switch
;
; Modified: 13-May-81, -2.0.11-, John D. Leonard
;	ADjusted overbar to back up slightly more than 1 reverse line feed.
;	The bars were not quite high enough for Capital letters.
;
; Modified: 03-Nov-81, -2.0.12-, John D. Leonard
;	Changed initial vertical paragraph and list spacing for 1/8 mode.
;	Increased size of list processing stack for LSTVS preserving.
;	Changed TOC page length to 54 lines as default.
	.ENDC
;-

	.SBTTL	RUNOFF GLOBAL DEFINITIONS

;	External Declarations

	.GLOBL	CMN		; Command parser
	.GLOBL	CRLF		; Output CR/LF
	.GLOBL	ENDFIL		; End of input file processing
	.GLOBL	ENOTE		; End of note pointer
	.GLOBL	FIN		; File input module
	.GLOBL	FLAGS		; Task context flags
	.GLOBL	FMSG		;
	.GLOBL	FORM		; Force output page with form-feeds
	.GLOBL	FOUT		; File output module
	.GLOBL	FREE		; Free allocated node
	.GLOBL	HYPHEN		; Hyphenation module
	.GLOBL	INTERR		;
	.GLOBL	LWCAS		;
	.GLOBL	OUTLUN		;
	.GLOBL	OUTPUT		;
	.GLOBL	PARTP		;
	.GLOBL	RNOERR		; Runoff error processing

;	SUBROUTINES

	.GLOBL	PPGNO			; page number output

	.sbttl	database externals

	.GLOBL	F.1			; Flags word
	.GLOBL	S1			; String pointer
	.GLOBL	TS1			; TOC string pointer
	.GLOBL	$CBON			; Change bars flags
	.GLOBL	$GCISW			; Input from re-read buffer flag
	.GLOBL	$HDSSW			; Disable page headers flag
	.GLOBL	$INSW			; Input file switches
	.GLOBL	$OUSW			; Output file switches
	.GLOBL	$SDISW			; Input from secondary buffer flag
	.GLOBL	$TOCSW			; TOC file switches

	.SBTTL	FLAG DEFINITIONS
	.MCALL	SVTK$,QIOW$S,GLUN$S,SAVE,UNSAVE

;
; Flag bits in F.1
;
;	Note: the low order byte corresponds to a legal command mask
;		that is tested against the trailing byte of the
;		appropriate command name.
;

NOTF==1				; note processing active
FOTF==2				; footnote processing active
RELF==4				; relative number conversion (1=yes)
FPGF==20			; flush pending page (1=yes)
ENDF==40			; corresponds to end flag in trailing byte
BRKF==100			; corresponds to break flag in trailing byte
JUSTF==400
PJUSTF==1000
FILLF==2000
LITFG==4000			; literal processing flag
SPECF==20000			; special command processing

;
; switch word flag bit definitions
;

FFDSW==1			; simulate form feeds (0=yes)
HYPSW==2			; hyphenate output text (1=yes)
PAUSW==4			; pause between pages (1=yes)
SPLSW==10			; spool text file (1=yes)
UPCSW==20			; force all text to upper case (1=yes)
DIASW==40			; terminal is a diablo
SPHDR==100			; no banner on header

;	pud characteristics flags

UC.TTY==4			; tty bit
UC.DIR==10			; directory device
UC.SDI==20			; single directory device
UC.OSP==4000			; output spooled

;	Change bar flags

CBBIT	==	1		; Change bar on
CBFBT	==	2		; Change bar just turned off

	.SBTTL	START OF DATABASE

	DATA	RNDATA

; simulated accumulator definitions

F.1::	.WORD	0			; flags word
S1::	.WORD	0			; string pointer
TS1::	.WORD	0			; Pointer used by TOC routines

;
; switch flags (byte)
;

$HDSSW::.BLKB	1		; disable page header (0=no)
$GCISW::.BLKB	1		; input from reread buffer (0=no)
$SDISW::.BLKB	1		; input from secondary input buffer (0=no)
$ULMSW::.BLKB	1		; underline mode (0=no backspace)
$ULNSW::.BLKB	1		; underline suppress (0=no)
$ULSSW::.BLKB	1		; underline simulate (0=no)
$SWPFL::.BLKB	1		; Swap output files (0=No)
$LINE1::.BLKB	1		; Enable line 1 output
$LINE2::.BLKB	1		; Enable line 2 output
$OPFLG::.BLKB	1		; OPRWAIT flag
$CHRFL::.BLKB	1		; Roman Numeral Chapter(0=no)
FINFLG::.BLKB	1		; File input flag.
PSTFLG::.BLKB	1		; Call to CCOUT from PSTRxx (sub/super bug)
	.EVEN

;
; switch flags (word)
;

HPHSW:	.BLKW	1		; hyphenation enabled for output (0=no)
TJFSW:	.BLKW	1		; temporary justify flag (0=no)
$CBON:: .BLKW	1		; Change bar on (0=NO)
$AUTSW::.BLKW	1		; autoparagraph active (0=no)
$CFLSW::.BLKW	1		; flag capitalize enable (0=no)
	.IF	DF	A$$RAP
$EQMFL::.BLKW	1		; flag to indicate .EQ in effect (0=no)
	.ENDC
$HDRSW::.BLKW	1		; print page headers (0=no)
$HFLSW::.BLKW	1		; flag hyphenate enable (0=no)
$HPHSW::.BLKW	1		; hyphenation active (0=no)
$NUMSW::.BLKW	1		; number pages (0=no)
	.IF	DF	A$$RAP
$OVPSW::.BLKW	1		; overprint switch
OVPFL	==	1		; overprint
OVPJFL	==	2		; overprint right justified
OVBFL	==	4		; overbar

	.ENDC
$PGPSW::.BLKW	1		; page pending (0=no)
$PERSW::.BLKW	1		; punctuation double spacing (0=no)
$SBPSW::.BLKW	1		; subpage mode flags word
	.IF	DF	A$$RAP
SBPON	==	1		; Enable subpage command pending
SBPSET	==	2		; Subpage printing active
SBPOFF	==	4		; End subpage command pending
	.ENDC
$ULLSW::.BLKW	1		; underline lock on (0=no)
	.IF	DF	A$$RAP
$OBLSW::.BLKW	1		; overbar lock on (0=no)
	.ENDC
$ULLS1::.BLKW	1		; underline sub or superscript (0=no)
$NUMLW::.BLKW	1		; number pages at bottom
$DATE::	.BLKW	1		; date present flag
$DATET::.BLKW	1		; TOC date present flag
	.IF	DF	A$$RAP
$MFAC::	.BLKW	1		; Multipication factor for number conversions
				; Used for 1/8 line specifications. (0=no)
	.ENDC


	.sbttl	Other areas (moved from RNORSX)

SPSAV::	.BLKW	1		; Stack pointer save area

$INSW:	.BLKW	1		; Input file switches
$OUSW:	.BLKW	1		; Output file switches
$TOCSW:	.BLKW	1		; Table of contents switches

ULSWT::	 .BLKB	2		; buffer for underline switch
RIGSHI:: .BLKW	1		; Buffer for shift value
PAGCNT:: .WORD	0		; total page count
	.IF	DF	A$$RAP
NFFCH::	.WORD	0		; Total # of formfeed characters output
	.ENDC

TOCSPC:: .BLKB	1		; .TOC file specified flag
LSTSPC:: .BLKB	1		; .LST file specified flag
	.even
FORMS::	.BLKW	1		; Output file forms type
COPIES:: .BLKW	1		; Output file forms type

	.SBTTL	SST VECTOR TABLE

SSTV::	SVTK$	TABL,7		; declare sst table

TABL:	.WORD	INTERR,INTERR,0,0,0,0,RNOERR	; sst vector table


	.SBTTL	IMPURE STORAGE

	.IF	DF	A$$RAP
ILMRG::	.WORD	0		; Initial left margin 10/12 pitch
IRMRG::	.WORD	0		; Initial right margin 10/12 pitch
	.ENDC
RMARG::	.WORD	0		; Current right margin
LMARG::	.WORD	0		; Current left margin
PRMRG::	.BLKW	1		; permanent right margin
PLMARG::.BLKW	1		; permanent left margin
PRMARG::.BLKW	1		; permanent right margin
	.IF	DF	A$$RAP
TMARG::	.WORD	0		; Margin at top of page
	.ENDC
CAS::	.WORD	0		; Character capitalize case conversion value
WCAS::	.BLKW	1		; word capitalize conversion value
APNDN::	.BLKW	1		; current appendix letter
CHPTN::	.BLKB	1		; current chapter number
	.BLKB	5		; current heading level numbers
CMADR::	.BLKW	1		; special processing command address
PAGENO::.WORD	0		; Current page number
PARPT::	.WORD	2		; paragraph page test count
PARSP::	.BLKW	1		; paragraph spacing count
PARIND::.WORD	0		; Paragraph indentation count
NSPNG::	.WORD	0		; Current spacing count
	.IF	DF	A$$RAP	; -2.0.1-
SSINC::	.WORD	0		; Sub/Super vertical inc. 1/2 space default
EQTPC::	.BLKW	1		; Equation mode test page count
EQSKP::	.BLKW	1		; Equation mode skip count before/after equation
EQSPC::	.BLKW	1		; Equation mode spacing
;
EQLMSV::.BLKW	1		; Save left margin when in EQ mode
EQSPSV::.BLKW	1		; Save spacing when in EQ mode
EQFLSV::.BLKW	1		; Save flags word in EQ mode
;
PITCH::	.BLKW	1		; Pitch, either 10 or 12
HSDEF::	.BLKW	1		; Default half space spacing for 10/12 pitch
HSPACE::.BLKW	1		; Bytes flipped on every half space. this is
				; because the Diablo can space 60/inch which
				; is 5 divisions/space 12 pitch, 6 for 10 pitch
				; For 12 pitch the high/low bytes are 2/3 and
				; for 10 pitch 3/3 so that in 12 pitch mode the
				; spacing will re-align after the 2nd halfspace.
	.ENDC
LINEC::	.WORD	0		; Count of lines on current page
SUBPGE::.WORD	0		; Current subpage number
	.IF	DF	A$$RAP
SYMMSK::.BLKW	1		; Flags bit mask for character type symbols
				; Passed to SETCHA when called from .SUBD/.SUB
	.ENDC
EBSIZ::	.BLKW	1		; Number of change bar initial spaces
LITCM::	.BLKW	1		; saved expected command address (literal)
LITSV::	.BLKW	1		; saved flags mask on literal processing
LSTPT::	.WORD	4		; list element page test count
LSTVS::	.BLKW	1		; list element verticle spacing
LSTKP::	.BLKW	1		; current list stack pointer
	.if	ndf	A$$RAP
LSTK::	.BLKW	5*3		; list stack (5 entries)
	.iff
LSTK::	.BLKW	5*4		; list stack (5 entries)
	.endc
LSTCT::	.BLKW	1		; current list element count
NOTCM::	.BLKW	1		; saved expected command address (note)
NOTLM::	.BLKW	1		; note saved left margin
NOTRM::	.BLKW	1		; note saved right margin
NOTSV::	.BLKW	1		; saved flag word on note processing
SPFIG::	.WORD	0		; number of pages to skip for figure
SPFIG1::.WORD	0		; in skipping figure pages
DATEBF::.BLKW	8.		; date buffer
	.WORD	0		; guard word
DATECT::.WORD	0		; count of characters
DATTBF::.BLKW	8.		; toc date buffer
	.WORD	0		; guard word
DATTCT::.WORD	0		; count of characters
INDXOF::.WORD	0		; number of spaces to move index page #



	.sbttl	Tab table, etc.

;	The following factor, TABTL, is used to determine the
;	size of the tabstop table. To increase the number of tabs,
;	increase this factor.

TABTL==32.			; Size of tabstop table
TABTAB::.BLKB	TABTL		; Tabstop table
NTABS::	.WORD	0		; Number of tabstops currently defined

NLPG::	.WORD	0		; Number of lines/page allowed
PNLPG::	.WORD	0		; Permanent(hardware) lines/page allowed
TPNLPG::.WORD	0		; TOC hardware lines/page

FOOTC::	.WORD	0		; Count of lines reserved for FN
FOOTLH:: .WORD	0		; Footnote listhead

XFIRST::.WORD	0			; Index buffer listhead
TOCLNL::.WORD	0		; TOC line length
TOCIND::.WORD	0		; TOC Indentation count
TLNCNT::.WORD	0		; TOC Count of lines on page
TPAGNO::.WORD	0		; TOC current page number

	.SBTTL	USER-SET TEMPS

INDCT::	.WORD	0		; Indentation count

;	The parameter, TTILIN, determines the buffer size of
;	the RUNOFF command line input buffer. The current buffer
;	is large enough to contain 4 80. character
;	command lines. This could probably be made smaller if the
;	command line continuation feature is not used excessively.

TTILIN==328.			; Set command line buffer size
TTIBUF::.BLKB	TTILIN		; Command line input buffer

; GENERAL	

LCH::	.WORD	0		; Last character processed on current line

LOWCHP::.WORD	0		; lowest chapter to print
HGHCHP::.WORD	0		; highest chapter to print

LOWPAG::.WORD	0		; lowest page to print
HGHPAG::.WORD	0		; highest page to print

PAGHD::	.BLKB	6		; page number text prototype
LPPG::	.BLKW	1		; hardware lines per page
HWLPP::	.WORD	HWPLN		; initial value for lppg
INI$SW::.WORD	HYPSW		; initial value for $insw
INO$SW::.WORD	FFDSW		; Initial value for $OUSW
INT$SW::.WORD	0		; Initial value for $TOCSW
IUL::	.WORD	'N		; initial underline switch
	.IF	DF	A$$RAP
UPDOWN::.BLKW	1		; Paper movement up/down control bytes
MOVUP::	.BYTE	PHLF		; Positive half line feed
	.BYTE	0		; No escape for 1/8 or full line feeds
MOVDWN::.BYTE	NHLF		; Negative half line feed
	.BYTE	ESC		; Need escape for 1/8 or full neg line feeds
	.ENDC

	.SBTTL	LINE TEMPS

LINBK::	.WORD	0		; Width of current line (RMARG-LMARG)
SPCNT::	.WORD	0		; Current spacing count
LSTSP::	.WORD	0		; Pointer to last space processed
LINNSC::.WORD	0		; Pointer to last non-spacing character

GCSCH::	.BLKB	1		; Saved character for re-processing
ULMCH::	.BLKB	1		; saved character for underlining
	.IF	DF	A$$RAP
	.BLKB	5		; additional storage for underline save chars.
	.EVEN
ULMCHP::.WORD	ULMCH		; pointer to ULMCH
	.ENDC

FOOTWB:: DH	322.		; Footnote save buffer

FOOTP1:: DH			; Header for footnote string

GCINP::	DH			; saved string for reprocessing(pointers only)

MSGBF::	DH	80.		; Message buffer

SDBUF::	DH	134.		; Secondary input buffer.

CMBF::	DH	134.		; RUNOFF command save buffer.

TTLBUF::DH	134.		; Title buffer

STTLBF::DH	134.		; Subtitle buffer

HFIN::	DH	322.		; Input buffer descriptor

	.IF	DF	A$$RAP
HFIN1::	DH	322.		; Alternate input buffer for string substitution
	.ENDC
HFOUT::	DH	254.		; Output buffer descriptor

	.IF	DF	A$$RAP
CSOUT::	DH	254.		; For dual font processing

	.ENDC
THFOUT:: DH	80.		; TOC buffer descriptor

LIBUF::	DH	322.		; Line input buffer

LOBUF::	DH			; Line output buffer

T1::	DH			; Temporary pointers for COMND

EXSP1::	.WORD	0		; Multiplier for all spaces
EXSP2::	.WORD	0		; Count of spaces, -,left,+,right
EXSP3::	.WORD	0		; Left/right spacing flag

NSPCH::	.WORD	0		; Count of non-spacing characters
LSTNSP::.WORD	0		; Address of last non-spacing char. on line
CPOS::	.WORD	0		; Current position on line
	.IF	DF	A$$RAP
VPOS::	.WORD	0		; Vertical position on line
OBCPOS::.WORD	0		; Overbar carriage position on line
	.ENDC
CHARCT:	.WORD	0		; temp location for form
CCOUTT::.WORD	0		; temp location for CCOUT

;	The underline position buffer is organized as follows.
;	The buffer contains position pointers on the current line
;	of characters to be underlined. Each time a character position
;	is added, the pointer, ULPOS, is updated to the next available
;	position. Therefore, to determine if anything is in the
;	underline buffer, all that has to be done is to compare the
;	pointer to the buffer starting address and if they are equal,
;	then no underlining was required on the line. If they
;	were unequal, then subtract the base from the pointer to get
;	a count of characters to be underlined.

ULPOS::	.WORD	0		; Next available slot in underline position buffer
ULPBF::	.BLKB	132.		; Underline position buffer
	.IF	DF	A$$RAP
OBPOS::	.WORD	0		; Next available slot in overbar position buffer
OBPBF::	.BLKB	264.		; Overbar position buffer

	.SBTTL	CS2DAT - Data area for dual character set handling
;
WHEEL1	==	1			; Indicate wheel 1 needed for this line
WHEEL2	==	2			; Indicate wheel 2 needed for this line
ESCFLG	==	4			; Set if last character was an escape
P2FLG	==	10			; Indicate change wheels line by line
GMFLG	==	20			; Indicate in graph mode in CS2OUT
BOVFLG	==	40			; OUTPUT called due to buffer overflow
CRFLG	==	100			; Carriage return on this line
FFFLG	==	200			; Form feed on this line
;
	.EVEN
CSVAL::	.WORD	-1			; From /CS:n switch. -1, CS2 not active.
CS2VP::	.WORD	0			; CS2 vertical position counter
$CS2FL::.BYTE	0			; Flag bits for CS2 processing
WHLNM::	.BYTE	WHEEL1			; Wheel needed at this point in line
CWHLN::	.BYTE	WHEEL1			; Current wheel in Diablo - swapped
	.BYTE	WHEEL2			; with byte 2 when wheel switched
WHLTO::	.BLKB	1			; Wheel to output for, 1 or 2
	.EVEN				; Always begin with wheel one.
;
;	Translate table for Diablo general scientific wheel vs. IBM keyboard
;
QUME	==	0		; ASSEMBLE FOR QUME GREEK WHEEL
TRTAB::
	.IF	NDF	QUME
	.BYTE	SPC	;SPACE
	.BYTE	'[	;!	Selectric
	.BYTE	'"	;"
	.BYTE	'#	;#
	.BYTE	'$	;$
	.BYTE	'%	;%
	.BYTE	'&	;&
	.BYTE	''	;'
	.BYTE	'(	;(
	.BYTE	')	;)
	.BYTE	'*	;*
	.BYTE	'+	;+
	.BYTE	',	;,
	.BYTE	'-	;-
	.BYTE	'.	;.
	.BYTE	'/	;/
	.BYTE	'0	;0
	.BYTE	'1	;1
	.BYTE	'2	;2
	.BYTE	'3	;3
	.BYTE	'4	;4
	.BYTE	'5	;5
	.BYTE	'6	;6
	.BYTE	'7	;7
	.BYTE	'8	;8
	.BYTE	'9	;9
	.BYTE	':	;:
	.BYTE	';	;;
	.BYTE	'~	;<	Selectric
	.BYTE	'=	;=
	.BYTE	'>	;>
	.BYTE	'?	;?
	.BYTE	'@	;@
	.BYTE	'A	;A
	.BYTE	'B	;B
	.BYTE	'C	;C
	.BYTE	'D	;D
	.BYTE	'E	;E
	.BYTE	'F	;F
	.BYTE	'G	;G
	.BYTE	'H	;H
	.BYTE	'I	;I
	.BYTE	'J	;J
	.BYTE	'K	;K
	.BYTE	'L	;L
	.BYTE	'M	;M
	.BYTE	'N	;N
	.BYTE	'O	;O
	.BYTE	'P	;P
	.BYTE	'Q	;Q
	.BYTE	'R	;R
	.BYTE	'S	;S
	.BYTE	'T	;T
	.BYTE	'U	;U
	.BYTE	'V	;V
	.BYTE	'W	;W
	.BYTE	'X	;X
	.BYTE	'Y	;Y
	.BYTE	'Z	;Z
	.BYTE	'!	;[	Selectric
	.BYTE	'\	;\
	.BYTE	'<	;]	Selectric
	.BYTE	'Y!200	;^	Selectric <esc> Y sign bit set as indicator
	.BYTE	'_	;_
	.BYTE	'`	;`
	.BYTE	'a	;a
	.BYTE	'b	;b
	.BYTE	'c	;c
	.BYTE	'd	;d
	.BYTE	'e	;e
	.BYTE	'f	;f
	.BYTE	'g	;g
	.BYTE	'h	;h
	.BYTE	'i	;i
	.BYTE	'j	;j
	.BYTE	'k	;k
	.BYTE	'l	;l
	.BYTE	'm	;m
	.BYTE	'n	;n
	.BYTE	'o	;o
	.BYTE	'p	;p
	.BYTE	'q	;q
	.BYTE	'r	;r
	.BYTE	's	;s
	.BYTE	't	;t
	.BYTE	'u	;u
	.BYTE	'v	;v
	.BYTE	'w	;w
	.BYTE	'x	;x
	.BYTE	'y	;y
	.BYTE	'z	;z
	.BYTE	'{	;{
	.BYTE	'|	;|
	.BYTE	'}	;}
	.BYTE	'~	;~
	.BYTE	127.	;DELETE
	.ENDC
	.IF	DF	QUME
	.BYTE	SPC	;SPACE
	.BYTE	'[	;!
	.BYTE	'^	;"	Selectric
	.BYTE	'#	;#
	.BYTE	'$	;$
	.BYTE	'>	;%	Selectric
	.BYTE	'&	;&	No equivalent (use large integral sign)
	.BYTE	''	;'
	.BYTE	'O	;(	No equivalent (use large right paren)
	.BYTE	'm	;)	No equivalent (use large left bracket)
	.BYTE	'N	;*	No equivalent (use large left paren)
	.BYTE	'|	;+	No equivalent (use large right bracket)
	.BYTE	',	;,
	.BYTE	' 	;-	No equivalent
	.BYTE	'.	;.
	.BYTE	'%	;/	No equivalent (use large right bracket)
	.BYTE	'0	;0
	.BYTE	'1	;1
	.BYTE	'2	;2
	.BYTE	'3	;3
	.BYTE	'4	;4
	.BYTE	'5	;5
	.BYTE	'6	;6
	.BYTE	'7	;7
	.BYTE	'8	;8
	.BYTE	'9	;9
	.BYTE	':	;:
	.BYTE	';	;;
	.BYTE	'_	;<	Selectric
	.BYTE	'(	;=	No equivalent (use large left bracket)
	.BYTE	'+	;>	No equivalent (use doulble dagger)
	.BYTE	'?	;?
	.BYTE	' 	;@	No equivalent
	.BYTE	'A	;A
	.BYTE	'B	;B
	.BYTE	'C	;C
	.BYTE	'D	;D
	.BYTE	'E	;E
	.BYTE	'F	;F	No equivalent (use less than or equals)
	.BYTE	'G	;G
	.BYTE	'`	;H	Pair of vertical parallel lines.
	.BYTE	'I	;I
	.BYTE	'J	;J	No equivalent (use greater than or equals)
	.BYTE	'-	;K	Small superscript division symbol
	.BYTE	'X	;L	Selectric
	.BYTE	'M	;M
	.BYTE	'f	;N	Selctric
	.BYTE	'L	;O	Selctric
	.BYTE	'P	;P
	.BYTE	'Q	;Q
	.BYTE	'R	;R
	.BYTE	'S	;S
	.BYTE	'T	;T
	.BYTE	'U	;U
	.BYTE	'~	;V	Selectric
	.BYTE	'W	;W
	.BYTE	'j	;X	Selectric
	.BYTE	'Y	;Y
	.BYTE	'Z	;Z
	.BYTE	'!	;[
	.BYTE	' 	;\	Undefined
	.BYTE	'<	;]
	.BYTE	'@	;^	No equivalent (use large summation sign)
	.BYTE	' 	;_	No equivalent
	.BYTE	' 	;`	Undefined
	.BYTE	'a	;a
	.BYTE	'b	;b
	.BYTE	'c	;c
	.BYTE	'd	;d
	.BYTE	'e	;e
	.BYTE	'=	;f	Minus/Plus
	.BYTE	'g	;g
	.BYTE	'h	;h
	.BYTE	'i	;i
	.BYTE	'/	;j	Angstrom symbol
	.BYTE	'k	;k
	.BYTE	'l	;l
	.BYTE	')	;m	Selectric
	.BYTE	'n	;n
	.BYTE	'o	;o
	.BYTE	'p	;p
	.BYTE	'q	;q
	.BYTE	'r	;r
	.BYTE	's	;s
	.BYTE	't	;t
	.BYTE	'u	;u
	.BYTE	'v	;v
	.BYTE	'w	;w
	.BYTE	'x	;x
	.BYTE	'y	;y
	.BYTE	'z	;z
	.BYTE	' 	;{	Undefined
	.BYTE	' 	;|	Undefined
	.BYTE	' 	;}	Undefined
	.BYTE	' 	;~	Undefined
	.BYTE	' 	;DELETE	Undefined
	.ENDC
	.EVEN
	.ENDC

	.SBTTL	Parameters

METBEG::			; Beginning of metacharacters
METSHU::.WORD	'^		; Upper case indicator
METSHD::.WORD	'\		; Lower case indicator
	.IF	NDF	R$$OCK
METQUO::.WORD	'_		; Quote next character
	.IFF
METQUO::.WORD	'>		; Quote next character
	.ENDC	; R$$OCK
METUNL::.WORD	'&		; Underline command in input data
ULCHS	==	32		; Underline char in internal storage
				; Must be .lt. QTS
METQSP::.WORD	'#		; Quoted (nonexpandable) space in input.
	.IF	NDF	R$$OCK
METSPC::.WORD	'{		; Superscript character
	.IFF
METSPC::.WORD	'@		; Superscript character
	.ENDC	; R$$OCK
	.IF	NDF	A$$RAP
SPCHS	==31			; Superscript in internal storage
	.ENDC
	.IF	DF	A$$RAP
SPCHS==20			; 20,21,22,23 - superscript 1/2,1/8,1/4,3/8
	.ENDC
	.IF	NDF	R$$OCK
METSBC::.WORD	'}		; Subscript character
	.IFF
METSBC::.WORD	'~		; Subscript character
	.ENDC	; R$$OCK
	.IF	NDF	A$$RAP
SBCHS	==	30		; Subscript in internal storage
	.ENDC
	.IF	DF	A$$RAP
SBCHS	==	24		; 24,25,26,27 Subscipt 1/2,1/8/1/4,3/8
	.ENDC
METNHY::.WORD	'=		; No hyphenation flag.
METCAP::.WORD	'<		; All caps flag
METILR::.WORD	'!		; In-line comments
	.IF	DF	A$$RAP
METCS2::.WORD	'%		; Font 2 character
CS2CHS	==	30		; Font 2 internal storage representaion
METOVB::.WORD	'$		; Overbar character
OBCHS	==	31		; internal representation
	.ENDC
METEND::			; End of metacharacters

;	These mnemonics must be in the same order as the metacharacters
;	to insure that the change command words properly
;
METTBB::.WORD	"UC		; upper case mnemonic
	.WORD	"LC		; lower case mnemonic
	.WORD	"QU		; quote character mnemonic
	.WORD	"UL		; underline mnemonic
	.WORD	"SP		; quoted space mnemonic
	.WORD	"SS		; superscript mnemonic
	.WORD	"SB		; subscript mnemonic
	.WORD	"NH		; no hyphenation mnemonic
	.WORD	"AC		; all caps mnemonic
	.WORD	"IC		; in-line commment mnemonic
	.IF	DF	A$$RAP
	.WORD	"CS		; font change mnemonic
	.WORD	"OB		; overbar
	.ENDC
METNUM::.WORD	<.-METTBB>/2	; number of mnemonics

	.IF	NDF	A$$RAP
DIVPL	==	2.		; Number of divisions per line for Diablo
	.IFF
FNCHAR::.BLKW	1		; Footnote termination character


DIVPL	==	8.		; Number of divisions per line for Diablo
MUL8	==	3		; Multiply by 8. using ASH 3,n
DIV8	==	-3		; Divide by 8. using ASH -3,n
HS10	==	3.*400 + 3.	; 10 pitch alternating half-space spacing
HS12	==	2.*400 + 3.	; 12 pitch alternating half-space spacing
	.ENDC
NLHDR	==	4.*DIVPL	; Number of lines to allow for header
NLFTR	==	3.*DIVPL	; Number of lines in footer - .NPL
HWPLN	==	66.*DIVPL	; hardware lines per page
ILSTTP	==	2		; initial list element page test count * spacing
ILSTVS	==	1*<DIVPL>	; initial list element vertical spacing
IPARIN	==	5		; initial paragraph indent
IPARTP	==	3		; initial paragraph page test * spacing
IPARPT	==	3		; default paragraph page test * spacing
IPARVS	==	1*DIVPL		; initial paragraph vertical spacing
	.IF	NDF	A$$RAP
IRMRG	==	60.		; initial right margin
ILMRG	==	0		; initial left margin
	.IFF
IRM10	==	75.		; initial right margin 10 pitch
ILM10	==	10.		; initial left margin 10 pitch
IRM12	==	90.		; initial right margin 12 pitch
ILM12	==	12.		; initial left margin 12 pitch
ITMRG	==	6.		; initial top margin  (1 inch)
;
IEQSKP	==	2*DIVPL		; initial eq mode blank skip
IEQSPC	==	1		; initial eq mode spacing = 1/8 line
IEQTPC	==	4*DIVPL		; initial eq mode test page count
	.ENDC
INLPG	==	54.*DIVPL	; initial length of page
INTLPG	==	54.		; Initial TOC length of page
LOLMAR	==	9.		; initial left margin indent on lists
LFSPAC	==	1*DIVPL		; final vertical spacing on lists
LSLMAR	==	4		; left margin indent on embedded lists
NASPAC	==	2*DIVPL		; vertical spacing after notes
NFSPAC	==	2*DIVPL		; final vertical spacing after notes
NHSPAC	==	2*DIVPL		; initial vertical spacing before notes
NPMARG	==	15.		; primary margin change on notes
NSMARG	==	4		; secondary margin change on notes
SDLPG	==	64.*DIVPL	; standard lines/page
SPARIN	==	0		; standard command paragraph indent
SPCNG	==	DIVPL		; standard line spacing
CBNSP	==	1		; Char offset for change bars

;	characters for cref

CR==15				; Carriage return
LF==12				; Line feed
SPC==40				; Space or blank
FF==14				; Form feed
BEL==7				; Bell
TAB==11				; Horizontal Tab
CMA==',				; Comma
ALT==33				; Altmode (ESCAPE)
	.IF	DF	A$$RAP
CS1=='1				; <esc> 1 - indicate font 1
CS2=='2				; <esc> 2 - indicate font 2
GMI=='3				; Set Diablo into  graph mode
GMO=='4				; Set Diablo out of gragh mode
	.ENDC
BS==10				; backspace character
NXS==177			; non-expandable space (internal representation)
QTS==37				; quoted space. must be spc-1 for compares
PD=='.				; period. for special spacing after period
EOF=='Z-100			; end of file (internal indicator)
LPUS=='_			; line-printer underscore in output file
SEMI=='; 			; semicolon
BAR=='|				; Change bar character
NHLF=='D			; negative half line feed for diablo
PHLF=='U			; positive half line feed for diablo
ESC==ALT			; Escape

	.SBTTL	START OF SUPPORT ROUTINES

	CODE	RNSUP

; input line
;	this routine inputs a line of text or command
;	from the source input file. It will pre-translate any
;	control characters, expand quoted spaces and characters, etc.

LIN::	CALL	GCIN		; read character with pre-translate
;	BITNE	#LITFG,F.1,10$	; procesing literal?
	CMPEQ	R1,#TAB,LTAB	; tab?
10$:	CMPNE	R1,#CR,20$	; not carriage return?
	JMP	LCR		; yes. Go look for lf

20$:	CMPEQ	R1,#NXS,LSPAC	; non expandable space?
	CMPEQ	R1,#SPC,LSPAC	; regular space?
	CMP	R1,#QTS		; some other control character?
	BGE	LIN3		; if ge no
	INC	LINBK		; account for nonspacing character
	INC	LINNSC		; Bump up count of non-spacing chars on line
	.IF	DF	A$$RAP	; -2.0.1-
	CMPNE	R1,#BS,LIN3	; Backspace character, allow 2 nsc's per bs
	INC	LINBK
	INC	LINNSC
	.ENDC

LIN3:	CALL	WLNIN1		; write char in input buffer (libuf)
	MOV	R1,LCH		; save as last character
	DEC	LINBK		; time to break line yet?
	BGE	LIN		; no. loop for more
	.IF DF	H$$PHN
	CLR	HPHSW		; clear hyphenate enable
	TSTEQ	$HPHSW,LIN3A	; no hyphenation active?
	BITEQ	#JUSTF,F.1,LIN3A ; no justification?
	BITEQ	#HYPSW,$INSW,LIN3A ; no hyphenation selected?
	MOV	LIBUF+BF.PTR,-(SP) ; remember end of line

FIN10:	CALL	GCIN		; get a character
	BITB	#CHAUC!CHALC,CHATBL(R1) ; Is it alphabetic?
	BEQ	FINEX		; EQ - no
	CALL	WLNIN1		; put character in buffer
	MOV	R1,LCH		; save in last character
	BR	FIN10		; go get another character

FINEX:	MOV	LSTSP,R0	; get address of last word
	INC	R0		; Point into word
	TSTB	(R0)		; is word to be hyphenated if possible?
	BMI	FIN06		; if mi no
	MOV	R1,-(SP)	; save last character
	MOV	LIBUF+BF.PTR,R1	; convert last word to asciz
	CLRB	(R1)		;  ...
10$:	BICB	#200,-(R1)	; erase all possible hyphenate disables
	CMP	R1,LIBUF+BF.ADR	; at front of line?
	BHI	10$		; if hi no
	MOV	SP,HPHSW	; enable hyphenate on output
	CALL	HYPHEN		; try to hyphenate the word
	MOV	LSTSP,R1	; address of last space
	MOV	2(SP),R0	; address of real end of line
	DEC	R0		; Back up a byte over extra character.

FIN02:	TSTB	-(R0)		; is this a place to insert a hyphen?
	BMI	FIN03		; yes
	CMP	R0,R1		; no, should i look farther?
	BHI	FIN02		; yes
	CLR	R1		; clear mask
	BR	FIN05
FIN03:;	SUB	#1,R0		; Point back
	MOV	R0,LSTSP	; set pointer to fake space
	INC	SPCNT		; count the fake space
	MOV	R1,R0		; get start of word
	MOV	#200,R1		; set bit mask
FIN05:	BICB	#200,(R0)+	; clear hyphen flag and test
	BNE	FIN05		; if ne more to go
FIN04:	MOV	LSTSP,R0	; Get buffer.
	BISB	R1,-(R0)	; Set last character for hyphenation
				; (possibly)
;	BISB	R1,@LSTSP	; reset the desired one only
	MOV	(SP)+,R1	; retrieve saved character
FIN06:	TST	(SP)+		; clean stack
	CALL	WLNIN1		; write character into buffer
LIN3A:
	.ENDC	; H$$PHN
	CALL	OUTLJ		; output line,justified if flags
	BR	LIN		; process next line.

	.SBTTL	SPECIAL CHARACTERS DURING LINE INPUT

;	this routine will handle all tabs on the current line

	.ENABL	LSB
LTAB:	MOV	LIBUF+BF.LEN,R2	; determine present position
	SUB	LINNSC,R2	; to present position
	ADD	LMARG,R2	; add in left margin
	ADD	INDCT,R2	; add in identation
	CALL	TABB		; find where next tab stop is
	CMP	R2,LINBK	; would that many equal or exceed line size?
	BGE	LSPAC		; yes. treat as space, not tab
	SUB	R2,LINBK	; and decrement linbk count by that amount

	MOV	#QTS,R1		; put n quoted spaces in buffer
10$:	CALL	WLNIN1		; output char to line buffer
	DEC	R2		; one less from total
	BGT	10$		; gt - then still some left on line

20$:	JMP	LIN

	.SBTTL	SPACE, NON-EX SPACE, INV. TAB

; here on space in input file, or on non-expandable space. also here on
; tab which couldn't be satisfied so is made a space
; not here on quoted spaces.

LSPAC:	BITEQ	#FILLF,F.1,30$	; no filling input beyond breaks?
	MOV	LIBUF+BF.PTR,R2	; filter out leading spaces
	CMP	R2,LSTSP	; is that where last space is?
	BLOS	20$		; if los yes

	MOV	LCH,R1		; get previous character what was it?
	CMPEQ	R1,#SPC,20$	; space?
	CMPEQ	R1,#NXS,20$	; non-expandable space?
	CMPEQ	R1,#QTS,20$	; quoted space?
	TSTEQ	$PERSW,30$	; one space after punctuation?
	CMPEQ	R1,#':,25$	; colon followed by a space?
	CMPEQ	R1,#SEMI,25$	; semicolon followed by a space?
	CMPEQ	R1,#'!,25$	; exclamation point followed by a space?
	CMPEQ	R1,#'?,25$	; question mark followed by a space?
	CMPNE	R1,#PD,30$	; not period followed by space?

25$:	TST	LINBK		; yes. any more room left?
	BLOS	30$		; no. just store the space
	CALL	50$		; update space pointers
	CALL	WLNIN1		; output character to output line
	DEC	LINBK		; and count following character
	MOV	#NXS,R1		; non-expandable space
	BR	40$		; go back for more
30$:	CALL	50$		; update space pointers
40$:	JMP	LIN3		; continue scanning line

;	this routine updates the spacing pointers and counters

50$:	MOV	LIBUF+BF.PTR,LSTSP ; here to store and count a space
	MOV	LINNSC,LSTNSP	; and non-spacing char posn
	INC	SPCNT		; count this space
	MOV	#SPC,R1		; space character (expandable)
	RETURN			;
	.DSABL	LSB

	.SBTTL	END OF BREAK COMMAND
;+
; endbcm--end of break command
;-

	.ENABL	LSB
ENDBCM::CALL	LINSET		; set for new line (break command)

	.SBTTL	END OF COMMAND
;+
; endcm--end of command
;-

ENDCM::	CALL	$FRCND		; force to logical end of line
	CMPEQ	R1,#PD,LGO	; period next character?
	CMPEQ	R1,#SEMI,LGO	; more text on line?
	BR	LCR		;

	.SBTTL	END OF LINE PROCESSING
;+
; end of line processing
;-

COMNT::	TST	(SP)+		; remove return from stack

LCR::	CALL	GCIN		; get file character

	CMPNE	R1,#LF,LCR	; not a linefeed?

	.SBTTL READ AND PROCESS NEXT LINE

LGO::	MOV	SPSAV,SP	; reload stack pointer
	CALL	CCIN		; read initial character on line

5$:	MOV	#F.1,R5		; point to flag mask word
	CMPNE	R1,#EOF,20$	; not end of file?
	BITEQ	#FOTF,(R5),10$	; not processing footnote?
	JMP	FOOTND		; go finish footnote processing

10$:	BIT	#TF.MOR,FLAGS	; any more input files ?
	BNE	12$		; ne - yes, skip flush
	CALL	OUTNJ		; flush out last line
	CLR	$HDRSW		; clear header print enable
	CALL	PAGEC		; force a page
	MOV	#100.,R3	; set page size
	CALL	TTESTP		; force a page
	.IF	DF	A$$RAP
	DEC	PAGCNT		; Adjust for # of pages message
	.ENDC
12$:	JMP	ENDFIL		; end of file

20$:	CMPEQ	R1,#FF,LGO	; formfeed on input?
	BITNE	#LITFG,(R5),70$	; processing literal?
	BITEQ	#FILLF,(R5),60$	; not filling from input file?
	TSTEQ	$AUTSW,60$	; autoparagraph not active?
	CMPEQ	R1,#CR,40$	; null line?
	BITB	#CHASP,CHATBL(R1) ; Is it a spacing character?
				; (space or tab)?
	BEQ	70$		; No - try for a command.
30$:	CALL	CCIN		; read next character
	BITB	#CHASP,CHATBL(R1) ; Is it any spacing character
				; (space or tab)?
	BNE	30$		; NE - yes
	CMPNE	R1,#CR,50$	; not carriage return?
40$:	CALL	CCIN		; bypass line feed
45$:	CALL	CCIN		; read next character
	BITB	#CHASP,CHATBL(R1) ; Is it any spacing character
				; (space or tab)?
	BNE	45$		; NE - yes
	CMPEQ	R1,#PD,90$	; leading period?
50$:	MOVB	R1,GCSCH	; save first character
	CALL	OUTNJ		; break current line
	CALL	PARTP		; perform paragraph break
	MOV	PARIND,INDCT	; set paragraph indent
	CALL	LINSET		; reset line parameters
	BR	TEXT		; process text
60$:	CMPEQ	R1,#CR,LCR	; null line?
70$:	CMPEQ	R1,#PD,90$	; period as first char?
	MOVB	R1,GCSCH	; save character

	.SBTTL	PROCESS LINE OF TEXT

TEXT::
	TSTEQ	$PGPSW,80$	; no page pending?
	.IF	NDF	A$$RAP
	CALL	PAGEC		; break page
	.IFF
	CALL	BPAGE		; break page
	.ENDC
80$:	BITNE	#FILLF,F.1,85$	; filling from input file?
	CALL	OUTLIN		; output line
	JMP	LIN		; and start another
85$:	JMP	LSPAC		;

90$:	CALL	CMN		; 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
	MOV	#ENDBCM,4(SP)	; set for break command
100$:
	BITEQB	#FPGF,(SP),110$	; don't perform pending page?
	TSTEQ	$PGPSW,110$	; no page pending?
	.IF	NDF	A$$RAP
	CALL	PAGEC		; perform page operation
	.IFF
	CALL	BPAGE		; perform page operation
	.ENDC
110$:	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
	.DSABL	LSB


	.SBTTL	ILLEGAL COMMAND
;
; illegal command
;

ILCM::	DIAG	ILCMM		; illegal command
	JMP	LCR		; and continue

	.SBTTL	OUTNJ -- OUTPUT LINE, NOT JUSTIFIED

; line output routine. three entry points

OUTNJ::	MOV	LIBUF+BF.PTR,R2	; here to output current line, not justified
	CALL	OUTNJ2		; call body of routine
	CLR	EXSP3		; clear left right spacing flag
OUTNJ3:	RETURN			;

;	OUTLJ -- Output line justified

OUTLJ:	MOV	LSTSP,R2	; end of line is last space, if any
	CMP	R2,LIBUF+BF.ADR	; Is line empty ?
	BHI	..036		; HI - No, attempt to justify

;	OUTLIN -- Set up line pointer for justify

OUTLIN:	MOV	LIBUF+BF.PTR,R2	; else end of input line
..036:	MOV	SP,TJFSW	; copy justify flag
	BITNE	#JUSTF,F.1,..037 ; justifying?

;	OUTNJ2 -- Output line, no-justified

OUTNJ2: CLR	TJFSW		; clear justify flag
	.IF DF	H$$PHN
	CLR	HPHSW		; clear hyphenate enable
	.IFTF

..037:	MOV	R2,LOBUF+BF.END	; save end of line to consider
	MOV	LIBUF+BF.ADR,LOBUF+BF.ADR ; and beginning.
	MOV	LOBUF+BF.ADR,LOBUF+BF.PTR ; ...
	MOV	R2,LOBUF+BF.LEN	; set length
	SUB	LOBUF+BF.ADR,LOBUF+BF.LEN ; ...
	CMP	R2,LOBUF+BF.ADR	; is the line empty?
	.IF	NDF	A$$RAP
	BLOS	OUTNJ3		; LOS - YES, Return
	.IFF
	BHI	25$		; No - proceed
	TSTEQ	$EQMFL,20$	; Empty and not in .EQ mode
	CALL	SKIPS		; If null line in .EQ mode - skip one
20$:	BR	OUTNJ3		; and return
25$:
	.ENDC

	TSTEQ	TJFSW,OUTNJ1	; not justifying line?
	TST	SPCNT		; yes, any spaces in line?
	BGT	30$		; if gt yes
	DIAG	JUSRM1		; DIAG -- Unable to justify line
	CLR	TJFSW		; clear justification
	BR	OUTNJ1		;

30$:	MOV	RMARG,R0	; yes. compute where to expand them
	SUB	LMARG,R0	; size of line
	SUB	INDCT,R0	; Less indent
	SUB	LOBUF+BF.LEN,R0	; Less length of line
	ADD	LSTNSP,R0	; compensate for non-spacing characters
	.IFT
	TSTEQ	HPHSW,..040	; no hyphenation on output?
	MOV	LSTSP,R1	; Get last byte to output + 1
	TSTB	-(R1)		; Last byte to have a hyphen?
;	TSTB	@LSTSP		; do we account for a hyphen?
	BPL	..040		; if pl no
	DEC	R0		; yes, decrement count
..040:
	.IFTF
	.IF NDF	R$$EIS		; If no EIS, use $DIV
	MOV	SPCNT,R1	; now find how many mult spaces each space is
	CALL	$DIV		; divide
	.IFF			; Otherwise, use DIV
	MOV	R0,R1		; Move into low order register
	.IF	DF	A$$RAP
	BITEQ	#DIASW,$INSW,35$	; Not diablo
	ASL	R1		; Double # of spaces to fill for halfspace filling
35$:
	.ENDC
	CLR	R0		; Clear high order register
	DIV	SPCNT,R0	; Find how many mult spaces each space is
	.ENDC	;R$$EIS
	MOV	R0,EXSP1	; multiplier for all spaces
	TSTNE	EXSP3,10$	; extras to left?
	NEG	R1		; right. get spaces before extras
	ADD	SPCNT,R1	; ..
10$:	MOV	R1,EXSP2	; store for later


OUTNJ1:	MOV	RIGSHI,R2	; Get right shift
	.IF	DF	A$$RAP
	ADD	PLMARG,R2	; And permanent left margin
	MOV	HSDEF,HSPACE	; Init half space alternation
	.ENDC
	CALL	NSPAC		; Do it
	MOV	INDCT,R2	; get indenting in case of paragraph
	CLR	INDCT		; (once only)
	ADD	LMARG,R2	; plus left margin
	.if	df	A$$RAP
	SUB	PLMARG,R2	; - permanent left margin
	.endc
	ADD	EBSIZ,R2	; Add on change bar size
	TST	EBSIZ		; Check if bar enabled
	BEQ	10$		; No so skip bar insertion
	TST	$CBON		; Is bar on ?
	BEQ	10$		; EQ - no
	MOV	R1,-(SP)	; Save r1 across call
	MOV	R2,-(SP)	; and R2
	BIC	#CBFBT,$CBON	; Clear the last bar bit
	MOV	#BAR,R1		; Insert change bar
	CALL	CCOUT		; And output it
	MOV	(SP)+,R2	; Restore R1
	MOV	(SP)+,R1	; Restore R1
	DEC	R2		; One less from count
10$:	CALL	NSPAC		; output that many spaces

OUTL1:	MOV	#LOBUF,R4	; Point to output buffer
	CALL	GCI		; read a character from output buffer
	.WORD	OUTLE		; end of output buffer
	CMPEQ	R1,#SPC,OUTSP	; real space?
	CMPNE	R1,#NXS,10$	; not non-expandable space?
	.IF	DF	A$$RAP
	TSTNE	$EQMFL,10$	; If in .EQ mode, '#' means half-space
	.ENDC
	MOV	#SPC,R1		; yes. make it one space
10$:
	.IFT
	MOV	R1,-(SP)
	BIC	#200,R1		; clear possible hyphenation flag
	.IFTF
	CALL	CCOUT		; output the character
	.IFT
	TSTB	(SP)+		; should hyphen be typed?
	BPL	OUTL1		; if pl no
	TSTEQ	HPHSW,OUTL1	; no hyphenation on output?
	MOV	#'-,R1
	CALL	CCOUT		; output it
	.ENDC
	BR	OUTL1		; loop back for more.
OUTSP:	CALL	CCSPC		; output a space
	TSTEQ	TJFSW,OUTL1	; not justifying line?
	.IF	NDF	A$$RAP
	MOV	EXSP1,R2	; yes. how many multiple spaces?
	CALL	NSPAC		; if any, send them.
	DEC	EXSP2		; to extra blanks yet?
	BGE	OUTS1		; no.
	TSTEQ	EXSP3,OUTS2	; spaces to right?
	BR	OUTL1		; left. no more extras, just loop
OUTS1:	TSTEQ	EXSP3,OUTL1	; no spaces left or right?
OUTS2:	CALL	CCSPC		; output a space
	.IFF
	CLR	R2		; How many spaces (or half spaces)
	DEC	EXSP2		; To extra spaces yet ?
	BGE	OUTS1		; No.
	TSTEQ	EXSP3,OUTS2	; Spaces to right ?
	BR	OUTS3		; left. No more extras just put out multiples
OUTS1:	TSTEQ	EXSP3,OUTS3	; No spaces left or right
OUTS2:	INC	R2		; Add one space
OUTS3:
	ADD	EXSP1,R2	; # of spaces to fill
	BITEQ	#DIASW,$INSW,20$	; Not diablo
	ASR	R2		; # of whole spaces
	BCC	20$		; No half spaces
	MOV	$EQMFL,-(SP)	; Save eq mode flag
	MOV	SP,$EQMFL	; Indicate .eq mode to get half space output
	MOV	#QTS,R1		;
	MOV	R2,-(SP)	; Save R2
	CALL	CCOUT		; Output the half space
	MOV	(SP)+,R2	; Restore R2
	MOV	(SP)+,$EQMFL	; Restore .eq mode flag
20$:
	CALL	NSPAC		; And output the whole spaces
	.ENDC
	BR	OUTL1		; and loop for rest of line


	.SBTTL	END OF LINE,FOOTNOTE PROCESSING

; end of line, and footnote processing

OUTLE:	COM	EXSP3		; complement left right flag
	MOV	LIBUF+BF.PTR,R2	; Get pointer to rest of line
	MOV	LIBUF+BF.ADR,LIBUF+BF.PTR ; reset line buffer
	CLR	LIBUF+BF.LEN	; reset length

	CMP	R2,LOBUF+BF.PTR	; any left to output?
	BLOS	OUTLE4		; no.
	MOV	LOBUF+BF.PTR,GCINP+BF.ADR ; Point to start of buffer for GCI
	MOV	LOBUF+BF.PTR,GCINP+BF.PTR ; Set up buffer for GCI
	MOV	R2,GCINP+BF.LEN		; Find the length
	SUB	GCINP+BF.ADR,GCINP+BF.LEN ;   ...

	COMB	$GCISW		; set to reread buffer

OUTLE4:	CALL	SKIPS		; ..
	TSTEQ	FOOTC,OUTFT1	; no footnote line commands declared?
OUTFT:	BITNE	#FOTF,F.1,OUTFT1 ; doing them already?
	MOV	NLPG,R2		; get starting footnote line
	SUB	FOOTC,R2	; reduce by requested lines
	CLR	FOOTC		; clear requested lines
	MOV	R2,NLPG		; save starting footnote line
	SUB	NSPNG,R2	; minus normal spacing
	CMP	R2,LINEC	; room on this page for footnote?
	BHI	OUTFT1		; if hi yes
	CALL	BPAGE		; break page here.
OUTFT1:	JMP	LINSET		; reset line paramaters

	.SBTTL	SKIPS - SKIP 1 LINE, USE SPACING COUNT

; subroutine to skip n lines on output file

SKIPS::	MOV	NSPNG,R2	; set to skip to next line
	BR	SKIPN		;

	.SBTTL	SKIP1 - SKIP 1 LINE ON THE OUTPUT PAGE

SKIP1::	MOV	#DIVPL,R2	; set to skip one line

	.SBTTL	SKIPN - SKIP N LINES ON THE OUTPUT PAGE

SKIPN::	MOV	R3,-(SP)	; save r3
	.IF	DF	A$$RAP
	CALL	OBOUT		; Output overbars if any
	.ENDC
	TSTNEB	$ULMSW,50$	; no need to consider saved underlines?
	MOV	#ULPBF,R3	; point to start of underline position buffer
	CMPEQ	R3,ULPOS,50$	; no underlines in the buffer?
	MOV	R2,-(SP)	; save number of lines to be output
	TSTNEB	$ULNSW,40$	; underlines suppressed?
	MOV	#LPUS,-(SP)	; assume underline via underline character
	TSTEQB	$ULSSW,10$	; use underline character?
	MOV	#'-,(SP)	; set character to dash
	ADD	#DIVPL,LINEC	; account for extra line
	CALL	CRLF		; space to next line
	BR	20$		;

10$:	MOV	#CR,R1		; output a carriage return
	CALL	FOUT		;
20$:	CLR	CPOS		; start at beginning of line
	MOV	HSDEF,HSPACE	; re-init alternating half spaces
30$:	MOVB	(R3),R2		; get position where underline goes
	BIC	#177400,R2	; No sign extend
	SUB	CPOS,R2		; how far to it?
	ASR	R2		; any half spaces ?
	BCC	35$		; no
	CALL	FHSPAC		; Yes do it and bump  carriage pointer
	INC	CPOS		;
35$:
	CALL	NSPAC		; space to the underline
36$:
	MOVB	(R3)+,R1	; Get current underline position
	BIC	#177400,R1	; Clear sign extend bits
	ADD	#2,R1		; Check contiguous underline characters
	CMPEQ	R3,ULPOS,38$	; at end of buffer
	CMPB	(R3),R1		; Contiguous position ?
	BLOS	36$		; Yes, check next one
38$:
	SUB	CPOS,R1		; Find # of underlines to output
	ADD	R1,CPOS		; update CPOS for underlines
	MOV	R1,-(SP)	; save it
	MOV	R1,R2		;
	ASR	R2		; halve the spacing
	MOV	2(SP),R1	; underline character
39$:
	CALL	FOUT		;
	SOB	R2,39$		;
	MOV	(SP)+,R2	;
	ASR	R2		; any half spaces ?
	BCC	391$		; no
	CALL	BHSPAC		; back up one half character and
	CALL	FOUT		; output the underlin
391$:
	CMPNE	R3,ULPOS,30$	; not to last underline?
	TST	(SP)+		; clean stack
40$:	CALL	ULBSET		; reset underline buffer pointer
	MOV	(SP)+,R2	; restore number of lines
50$:	ADD	R2,LINEC	; count lines
	CLR	NSPCH		; clear per-line counts
	CLR	CPOS		; ..
	CMP	LINEC,NLPG	; Compare current position with length
	BLE	55$		; less than page
	SUB	R2,LINEC	; Reset line count so lower numbering is not off
	CALL	BPAGE		; Have to break the page
	BR	70$		; Ignore rest of line skips
55$:
	.IF	NDF	A$$RAP
	ASR	R2		;
	BCC	60$		;
	BIT	#DIASW,$INSW	; diablo on ?
	BEQ	60$		; eq - no
	MOV	#ESC,R1		; output an escape
	CALL	FOUT		;  ..
	MOV	#PHLF,R1	; now for a half line feed
	CALL	FOUT		;  ...
	MOV	#CR,R1		; and carriage return if spacing is 1
	CALL	FOUT		;  ...
60$:	TST	R2		; Zero lines to output
	BLE	65$		; EQ - then don't skip any lines
62$:	CALL	CRLF		; Space to next line
	DEC	R2		; Output as many as requested
	BGT	62$		; If GT yes
	.IFF
	CALL	SKIPDI		; Skip the lines (move paper up)
	.ENDC
65$:	MOV	NSPNG,R3	; Get spacing count to next line
	CALL	TESTP		; test if page should be broken
70$:	MOV	(SP)+,R3	; Restore R3
	RETURN
	.IF	DF	A$$RAP

	.SBTTL	OBOUT -- Overbar output

OBOUT::
	MOV	#OBPBF,R3	; point to start of overbar position buffer
	CMPEQ	R3,OBPOS,250$	; no overbars in the buffer?
	MOV	HSDEF,HSPACE	; re-init alternating half spaces
	MOV	R2,-(SP)	; save number of lines to be output
	MOV	#CR,R1		; output a carriage return
	CALL	FOUT		;
;	MOV	#ESC,R1		; and neqative line feed
;	CALL	FOUT		;
;	MOV	#LF,R1		;
;	CALL	FOUT		;
	MOV	#9.,R2		; Back up 1 and 1/8 lines
	CALL	SKIPDN		; Move the paper
	CLR	CPOS		; start at beginning of line
30$:	MOVB	(R3),R2		; get position where overbar goes
	BIC	#177400,R2	; Clear off sign bits
	SUB	CPOS,R2		; how far to it?
	ASR	R2		; # of whole spaces
	BCC	50$		; no half spaces
	CALL	FHSPAC		; output a halfspace
	INC	CPOS		; bump position pointer
50$:	CALL	NSPAC		; space to the overbar
	CLR	R2		; Assume no further vertical movement
100$:
	MOVB	(R3)+,R1	; Get current overbar position
	BIC	#177400,R1	; Clear off sign extend bits
	ADD	#2,R1		; Update to check next contiguous position
	CMPB	(R3)+,R2	; Find highest super script over which to
	BGE	120$		; overbar - it's negative for neg line feeds.
	MOVB	-1(R3),R2	; This one is higher than previous
120$:	CMPEQ	R3,OBPOS,140$	; At end of overbar buffer, print it
	CMPB	(R3),R1		; next overbar is next to last one, loop til not
	BLOS	100$		;
140$:	NEG	R2		; change to pos # of lines
	MOV	R2,-(SP)	; Save for reposition later
	SUB	CPOS,R1		; # of overbars to output
	ADD	R1,CPOS		; Update CPOS for overbars
	MOV	R1,-(SP)	; Save til after skip
	CALL	SKIPDN		; Move paper down additional 1/8 lines if any
	MOV	(SP),R2		; # of overbars to output
	ASR	R2		; whole overbars
	MOV	#LPUS,R1	; Overbar character
150$:	CALL	FOUT		;
	SOB	R2,150$		; Loop till done
	MOV	(SP)+,R2	; any half overbars ?
	ASR	R2		;
	BCC	170$		; no, proceed
	CALL	BHSPAC		; back-up a half space and
	CALL	FOUT		; put out one more overbar
170$:
	MOV	(SP)+,R2	; Reposition paper
	CALL	SKIPUP		; back up
	CMPNE	R3,OBPOS,30$	; not to last overbar?
	CALL	OBBSET		; reset overbar buffer pointer
	MOV	#9.,R2		; Readjust line position
	CALL	SKIPUP		; Move paper up
	MOV	(SP)+,R2	; Restore R2
;	MOV	#LF,R1		; Line feed to
;	CALL	FOUT		; space back down to original position
	MOV	#CR,R1		; and return carriage to left margin for new line
	CALL	FOUT		;
	CALL	FLUSH		; Clear the buffer

250$:	RETURN

	.sbttl	FHSPAC	-- output forward half space

FHSPAC::
	SAVE	R0,R1		;
	CALL	GMIN		; graph mode
	MOVB	HSPACE,R0	; # spaces to make a half space
	MOV	#SPC,R1		; Blank
100$:	CALL	FOUT		; output them
	SOB	R0,100$		; Loop till done
	CALL	GMOUT		; exit graph mode
	SWAB	HSPACE		; alternate half-spacing if 12 pitch
	UNSAVE	R0,R1		; restore registers
	RETURN			;

	.SBTTL	BHSPAC	-- Backward half space

BHSPAC::
	SAVE	R0,R1
	MOV	#BS,R1		; backup one full space and
	CALL	FOUT		;
	CALL	FHSPAC		; move forward a half space
	UNSAVE	R0,R1		;
	RETURN

	.SBTTL	SKIPDI/UP/DW - Move paper up or down on diablo

	.ENABL	LSB
SKIPDI::CALL	FLUSH		; Flush output buffer before spacing
	MOV	#CR,R1		; Carriage return
	CALL	FOUT		;
	CALL	SKIPUP		; Move paper up
	CALL	FLUSH		; start clean for new line
	RETURN

SKIPUP::MOV	MOVUP,UPDOWN	; Set control bytes for upward movement
	BR	10$

SKIPDN::MOV	MOVDWN,UPDOWN	; Set control bytes for downward paper movement

10$:	MOV	R2,-(SP)	; Save skip count (# of 1/8 lines to skip)
	BIC	#177770,R2	; See if any partial lines to output
	BEQ	100$		; No, just full line feeds

	BITEQ	#<DIVPL/2>,R2,20$	; Any half line feeds ? (eq = none)
	MOV	#ESC,R1		; Output <esc> U or D
	CALL	FOUT		;
	MOVB	UPDOWN,R1	; Set to either 'U or 'D at entry to routine
	CALL	FOUT		; and do it

20$:	BIC	#<DIVPL/2>,R2	; Clear half lines and see if have 1/8 lines to do
	BEQ	100$		; Nope - go on to do full line feeds
	CALL	GMIN		; 1/8 lines in graph mode
30$:	MOVB	UPDOWN+1,R1	; <esc> if down, 0 if up
	BEQ	40$		; move paper up
	CALL	FOUT		; <esc><LF> to move paper down
40$:	MOV	#LF,R1		;
	CALL	FOUT		;
	SOB	R2,30$		; Loop on # of 1/8 line feeds to put out
	CALL	GMOUT		; Exit graph mode after 1/8 lines

100$:	MOV	(SP)+,R2	; Retreive original # of 'lines' to skip
	ASH	#DIV8,R2	; Get rid of 1/8 lines
	BEQ	140$		; No full lines either
120$:	MOVB	UPDOWN+1,R1	; up or down ?
	BEQ	130$		; up
	CALL	FOUT		;
130$:	MOV	#LF,R1		; and put out the line feed
	CALL	FOUT		;
	SOB	R2,120$		; loop till done

140$:	RETURN			;
	.DSABL	LSB
	.ENDC

	.SBTTL	FORM -- SPACE TO TOP OF FORM

; routine to space to top of form

FORM:	MOV	LINEC,R2	; get current line position
	BNE	150$		; if not equal not at top
	.IF	NDF	A$$RAP
	JMP	60$		; if eq already at top
	.IFF
	TSTNE	SPFIG1,150$	; Go skip figure pages if non-zero
	JMP	340$		; if eq already at top
	.ENDC
150$:
	.IF	NDF	A$$RAP
	TSTNE	$SBPSW,12$	; doing a subpage?
	INC	PAGENO		; increment page
	BR	13$
12$:	INC	SUBPGE		; increment subpage
13$:
	.IFF
	CALL	FLUSH
	.ENDC
	TSTEQ	$NUMSW,1$	; numbering pages?
	TSTEQ	$NUMLW,1$	; numbering low on page?
	.IF	NDF	A$$RAP
	TSTNE	SPFIG1,6$	; already doing figure pages?
	.ENDC
	MOV	PNLPG,R2
	SUB	LINEC,R2
	.IF	NDF	A$$RAP
	ADD	#<2*DIVPL>,R2
	.IFF
	SUB	#DIVPL,R2	; minus one line to get to print line
	BGT	5$		; Check if already past end-of-page
	MOV	#DIVPL,R2	;
5$:
	.ENDC
	ADD	R2,LINEC
	.IF	NDF	A$$RAP
	ASR	R2		;
	BCC	5$
	BIT	#DIASW,$INSW
	BEQ	5$
	MOV	#ESC,R1
	CALL	FOUT
	MOV	#PHLF,R1
	CALL	FOUT
5$:	CALL	CRLF
	DEC	R2
	BGT	5$
	.IFF
	CALL	SKIPDI		; Skip to botton of page
	.ENDC
6$:	CLR	R2
	MOVB	CHPTN,R3
	BEQ	100$
	MOV	R3,R0
	CALL	PPGNO
	DEC	R2
100$:	MOV	PAGENO,R0
	.IF	DF	A$$RAP
	CMPNE	#1,R0,30$	; If page one, don't number
	BITEQ	#SBPSET,$SBPSW,1$	; Page one and no subpage - skip it
30$:
	.ENDC
	CALL	PPGNO
	.IF	NDF	A$$RAP
	TSTEQ	$SBPSW,80$		; No subpage ?
	.IFF
	BITEQ	#SBPSET,$SBPSW,80$	; no subpage?
	.ENDC
	DEC	R2		; make room for letter
80$:	MOV	R2,CHARCT	; save number of characters
	ADD	PRMARG,R2	; calculate number of spaces
	SUB	PLMARG,R2	; to skip for page number
	ASR	R2
	ADD	PLMARG,R2
	SUB	R2,CHARCT	; calculate total number of spaces
	CALL	NSPAC		; space to page number
	TSTEQ	R3,120$		; no chapter or appendix specified
	MOV	APNDN,R1	; get current appendix number
	BEQ	90$		; if equal none specified
	ADD	#'A-1,R1	; change to upper case ascii
	CALL	FOUT		; output character
	BR	110$
90$:	MOV	R3,R0		; set chapter number
	CALL	DECPRT		; output chapter number
110$:	MOV	#'-,R1		; output a dash
	CALL	FOUT
120$:	MOV	PAGENO,R0	; get current page number
	CALL	DECPRT		; output page number
	.IF	NDF	A$$RAP
	TSTEQ	$SBPSW,130$
	.IFF
	BITEQ	#SBPSET,$SBPSW,130$	; Subpage ?
	.ENDC
	MOV	SUBPGE,R1	; SUBPGE contains lower case 'a' initially
	.IF	NDF	A$$RAP
	ADD	#' ,R1
	.ENDC
	CALL	FOUT
130$:	TSTEQ	$DATE,1$	; is there a date
	MOV	CHARCT,R2
	SUB	DATECT,R2
	ADD	PRMARG,R2
	CALL	NSPAC		; space over to new date
	MOV	DATECT,R2	; get number of characters
	MOV	#DATEBF,R3	; where to get characters
140$:	MOVB	(R3)+,R1	; get character
	CALL	FOUT		; output character
	SOB	R2,140$		; done?
1$:	MOV	#CR,R1
	CALL	FOUT
	CALL	LINSET
	.IF	NDF	A$$RAP
	TSTEQ	SPFIG1,11$	; doing figure pages skip
	CALL	CRLF		; yes, do cr/lf to force new pages if .NNM
	ADD	#2,LINEC	; increment line count
	BR	40$
	.ENDC
11$:	CALL	FFEED		; output a formfeed
40$:
	.IF	DF	A$$RAP
	BITNE	#SBPOFF,$SBPSW,41$	; That was the last subpage
	BITNE	#<SBPON!SBPSET>,$SBPSW,42$	; Subpage ?
41$:	INC	PAGENO		; No, Bump page number
	BR	43$
42$:
	BITEQ	#SBPSET,$SBPSW,43$	; If not set don't increment page count
	INC	SUBPGE		; Yes, bump subpage letter
43$:
	.ENDC
	CALL	OPRWAT		; see if wait is required
	.IF	NDF	A$$RAP
	TSTEQ	SPFIG,60$	; any figures
	DEC	SPFIG		; decrement counter
	MOV	SPFIG,SPFIG1	; set doing figure page flag
	JMP	150$		; output a new page
60$:	CLR	SPFIG1		;
	.IFF
	BITEQ	#SBPON,$SBPSW,300$	; subpage pending ?
	BIS	#SBPSET,$SBPSW		; Yes set subpage active flag and
	BIC	#SBPON,$SBPSW		;	clear pending flag
	MOV	#'a,SUBPGE		; Init subpage number
300$:
	BITEQ	#SBPOFF,$SBPSW,340$	; End subpage pending ?
	CLR	$SBPSW			; Clear all subpage flags
340$:
	MOV	TMARG,R2	; Top Margin ?
	BLE	350$		; none
345$:	CALL	CRLF		; space down
	SOB	R2,345$		; Loop till done
350$:				;
	CALL	FLUSH		; Make sure output buffer is clear for /cs:n
	.ENDC
	RETURN			;

	.SBTTL	BREAK PAGE AND OUTPUT HEADING

; routine to break page and output heading

	.ENABL	LSB
PAGEC::
	.IF	NDF	A$$RAP
	CLR	$SBPSW		; clear subpage flag
	MOV	#SPC,SUBPGE	; reset subpage number
	.IFF
	BIS	#SBPOFF,$SBPSW	; Indicate subpage numbering terminating after
				; this page is flushed.
	.ENDC
	BR	BPAGE		;
TPAGE::
	.IF	NDF	A$$RAP
	MOV	SP,$SBPSW	; set subpage flag
	TSTEQ	$NUMLW,310$	; numbers at bottom of page ?
	JMP	LGO
	.IFF
	BITEQ	#SBPSET,$SBPSW,300$	; If set, don't re-init subpage
	JMP	LGO			; Already doing subpage
300$:	BIS	#SBPON,$SBPSW	; Indicate subpage numbering pending
	BR	310$
	.ENDC
305$:	JMP	50$
310$:
	.IF	NDF	A$$RAP
	INC	SUBPGE		; increment subpage
	.ENDC
BPAGE::
	CLR	$PGPSW		; clear page pending flag
	BITNE	#FOTF,F.1,305$	; already processing a footnote?
	TSTEQ	FOOTP1+BF.LEN,305$ ; Any data in footnote buffer
	MOV	NLPG,R2		; get starting footnote line
	MOV	#2000.,NLPG	; set large count
	SUB	LINEC,R2	; calculate distance to first footnote
	BLOS	10$		; if los some left to go
	CALL	SKIPN		; skip to end of page before footnotes
10$:	MOV	R5,-(SP)	; save register r5
	MOV	#F.1,R5		; point to flag word
	MOV	$CBON,-(SP)	; Save change bars flags around footnote
	MOV	RMARG,-(SP)	; save these items over footnote processing
	MOV	LMARG,-(SP)
	MOV	PARIND,-(SP)	; save para indenting
	MOV	NSPNG,-(SP)
	MOVB	GCSCH,-(SP)
	MOV	INDCT,-(SP)	; occassionally we need to save this
	MOV	(R5),-(SP)	; save current flag word
	CLR	INDCT		; clear it for random failures
	CLR	$CBON		; Reset change bars for footnotes
	MOV	PLMARG,LMARG	; reset left margin
	MOV	PRMARG,RMARG	; reset right margin
	CLRB	GCSCH		; clear saved character
	MOV	FOOTWB+BF.ADR,FOOTWB+BF.PTR ; Say buffer is empty
	CLR	FOOTWB+BF.LEN	; clear length
	MOVB	$GCISW,-(SP)	; save reread flag
	BEQ	30$		; if eq not set
20$:	MOV	#GCINP,R4	; Point to saved character buffer
	CALL	GCI		; Get character from buffer
	.WORD	30$		; None left, then leave
	MOV	#FOOTWB,R4	; Point to footnote save buffer
	CALL	WCI		; Write char. into save buffer
	BR	20$		; loop until saved buffer all moved

30$:	CLRB	$GCISW		; clear reread buffer flag
	MOV	SPSAV,-(SP)	; save base of stack
	MOV	SP,SPSAV	; set new stack base
	BIS	#FOTF,(R5)	; set footnote processing active
	CALL	LINSET		; initialize line for start of footnote
40$:	JMP	LGO		; and go process saved footnote commands

	.SBTTL	END OF FOOTNOTE PROCESSING
;
;  end of footnote processing
;

FOOTND:	CALL	OUTNJ		; yes. finish up line

;	Free space used by current footnote

	MOV	FOOTLH,R1	; Get list head
	BEQ	43$		; EQ - then at end of list, resume normal duty
	MOV	FN.FWD(R1),FOOTLH ; Point to next list item
	CALL	FREE		; Free the space

;	Link back to last footnote

	MOV	FOOTLH,R1	; Get next link
	BEQ	43$		; EQ - then finish list

	MOV	FN.P1(R1),FOOTP1+BF.ADR ; Reset pointers
	MOV	FN.P2(R1),FOOTP1+BF.PTR ; ...
	MOV	FN.P3(R1),FOOTP1+BF.END ; ...
	MOV	FN.P4(R1),FOOTP1+BF.LEN ; ...
	
	BR	42$		; Go process next footnote

;	End of footnote list reached, link back to free list

43$:	CLR	FOOTLH		; Show no more footnotes active
	CLR	FOOTP1+BF.ADR	; Reset buffer
	CLR	FOOTP1+BF.PTR	;  ...
	CLR	FOOTP1+BF.END	;  ...
	CLR	FOOTP1+BF.LEN	;  ...
	BR	41$		; And do no more for now

42$:	TSTNE	FOOTP1+BF.LEN,40$ ; any more footnotes to process?

41$:	CLR	EXSP3		; clear left right flag
	MOV	SPSAV,SP	; reset stack to current base
	MOV	(SP)+,SPSAV	; restore old stack base
	MOVB	(SP)+,$GCISW	; restore reread flag
	MOV	(SP)+,(R5)	; restore flag word
	MOV	(SP)+,INDCT	; restore indent count
	MOVB	(SP)+,GCSCH	; restore saved character
	MOV	(SP)+,NSPNG	; restore current spacing
	MOV	(SP)+,PARIND	; restore paragraph indent
	MOV	(SP)+,LMARG	; restore left margin
	MOV	(SP)+,RMARG	; restore right margin
	MOV	(SP)+,$CBON	; Restore change bars flags
	BIC	#FOTF,(R5)	; clear footnote processing flag
	MOV	(SP)+,R5	; restore register R5
	MOV	PNLPG,NLPG	; reset length of page
	.IF	DF	A$$RAP
	SUB	$NUMLW,NLPG	; Adjust for footer if any.
	.ENDC
	MOV	FOOTWB+BF.ADR,GCINP+BF.ADR ; restore reread descriptor
	MOV	FOOTWB+BF.ADR,GCINP+BF.PTR ; 2.0.2 point to start of bufffer
	MOV	FOOTWB+BF.LEN,GCINP+BF.LEN ; Restore length

50$:	CALL	FORM		; output formfeeds or linefeeds
	.IF	NDF	A$$RAP
	CALL	SKIP1		; skip one line
	.ENDC
	TSTNE	$HDRSW,52$	; no headers to be printed?
	JMP	133$		; Return
52$:	MOV	#<4*DIVPL>,R2	; assume
	TSTB	$HDSSW		; Are headers disabled ?
	BEQ	53$		; EQ - no
	JMP	130$		; Else skip header stuff
53$:	MOV	PLMARG,R2	; get left margin
	ADD	RIGSHI,R2	; Add space for right shift
	ADD	EBSIZ,R2	; Add on space for change bar offset
	CALL	NSPAC
	MOV	#TTLBUF,R4	; Output title to file
	MOV	BF.LEN(R4),-(SP) ; Save length
	MOV	BF.PTR(R4),-(SP) ; And pointer
	CALL	PSTRPA		; print string from pa
	MOV	(SP)+,BF.PTR(R4) ; Restore pointer
	MOV	(SP)+,BF.LEN(R4) ; Restore length
	TSTB	$LINE1		; Is line 1 active ?
	BNE	120$		; Yes, skip page #
	TSTEQ	$NUMSW,120$	; no page number?
	TSTNE	$NUMLW,120$	; number low skip
	MOV	PRMARG,R2	; find position where this left us
	BITEQ	#SPECF,F.1,55$	; no special handling in progress?
	CMPNE	ENOTE,CMADR,55$	; not processing a note?
	MOV	NOTRM,R2	; get right margin before note
55$:	SUB	BF.LEN(R4),R2	; Less width of line
	.IF	DF	A$$RAP
	SUB	PLMARG,R2	; Adjust for left margin
	.ENDC
	.IF	NDF	A$$RAP
	TSTEQ	$SBPSW,60$	; no subpage?
	.IFF
	BITEQ	#SBPSET,$SBPSW,60$	; no subpage ?
	.ENDC
	DEC	R2		; make room for letter
60$:
	.IF	DF	A$$RAP
	CMPEQB	#SPC,PAGHD,65$	; If blank don't account for 'PAGE '
	.ENDC
	SUB	#5.,R2		; adjust for space required by 'page '
65$:	MOV	APNDN,R3	; get current appendix level
	BEQ	70$		; if eq none specified
	CMPB	-(R2),-(R2)	; adjust for appendix letter and dash
	BR	80$		;
70$:	MOVB	CHPTN,R3	; get current chapter number
	BEQ	80$		; if eq none specified
	MOV	R3,R0		; calculate space count for chapter number
	CALL	PPGNO		;
	DEC	R2		; adjust for dash
80$:	MOV	PAGENO,R0	; get current page number
	CMPEQ	#1,R0,120$	; page number one?
	CALL	PPGNO		; calculate space count for page number
	CALL	NSPAC		; space to page number
	.IF	DF	A$$RAP
	CMPEQB	#SPC,PAGHD,85$	; Skip 'page ' if blanked out
	.ENDC
	MOV	#PAGHD,S1	; set address of output message
	CALL	FMSG		; output 'page '
85$:	TSTEQ	R3,110$		; no chapter or appendix specified?
	MOV	APNDN,R1	; get current appendix letter
	BEQ	90$		; if eq none specified
	ADD	#'A-1,R1	; convert to upper case ascii
	CALL	FOUT		; output appendix letter
	BR	100$		;
90$:	MOV	R3,R0		; set chapter number
	CALL	DECPRT		; output chapter number
100$:	MOV	#'-,R1		; output a dash
	CALL	FOUT		;
110$:	MOV	PAGENO,R0	; get current page number
	CALL	DECPRT		; output page number
	.IF	NDF	A$$RAP
	TSTEQ	$SBPSW,120$	; no subpage?
	.IFF
	BITEQ	#SBPSET,$SBPSW,120$	; No subpage ?
	.ENDC
	MOV	SUBPGE,R1	; retrieve the letter
	.IF	NDF	A$$RAP
	ADD	#' ,R1		; make an ascii letter
	.ENDC
	CALL	FOUT		; get it into output buffer
120$:	CALL	SKIP1		; skip one line
	MOV	PLMARG,R2	; get left margin
	ADD	RIGSHI,R2	; add in right shift if any
	ADD	EBSIZ,R2	; add in space for change bars
	CALL	NSPAC		; space over
	MOV	#STTLBF,R4	; output the subtitle, if any
	MOV	BF.LEN(R4),-(SP) ; Save length
	MOV	BF.PTR(R4),-(SP) ; Save pointer
	CALL	PSTRPA		; print string from pa
	MOV	(SP)+,BF.PTR(R4) ; Restore pointer
	MOV	(SP)+,BF.LEN(R4) ; Restore length
	MOV	#<3*DIVPL>,R2	; and output this line.
130$:	CLRB	$HDSSW		; enable header
	CALL	SKIPN		; including subtitle, and return from bpage
133$:
	.IF	DF	A$$RAP
	MOV	SPFIG,SPFIG1	; Figure pages skip flag
	TSTEQ	SPFIG,136$	; Need to skip any figure pages ?
	DEC	SPFIG		; Decrement by one and go skip a page
	JMP	BPAGE		;
136$:
	.ENDC
	RETURN

	.SBTTL	PPGNO -- PAGE NUMBER OUTPUT

; subroutine for page number output

PPGNO:	CMP	#100.,R0	; three digit number
	BGT	140$		; if gt no
	DEC	R2		; adjust for hundreds digit
140$:	CMP	#10.,R0		; two digit number?
	BGT	150$		; if gt no
	DEC	R2		; adjust for tens digit
150$:	DEC	R2		; adjust for ones digit
160$:	RETURN			;
	.DSABL	LSB

	.SBTTL	FFEED -- SPACE TO TOP OF FORM

;
;	routine to space to top of form
;
FFEED::	TST	LOWCHP		; Low chapter number in effect?
	BNE	1$		; Yes
	TST	LOWPAG		; Low page number in effect?
	BEQ	5$		; No
1$:	CALL	OUTPUT		; Otherwise, force out buffer.

5$:	INC	PAGCNT		; bump up total page count

	BITEQ	#FFDSW,$OUSW,10$ ; spacing with line feeds?
	MOV	#FF,R1		; output a formfeed
	CALL	FOUT
	BR	30$		; adjust counts
10$:	MOV	LINEC,R2	; get line position
15$:	SUB	#HWPLN,R2	; get - number of lines to top of page
	BPL	15$		; if pl loop
;
;	Note - Assume if Diablo we're using hardware formfeeds.
;
20$:	CALL	CRLF		; space to next line
	INC	R2
	BLT	20$
30$:	CLR	LINEC		; current line now zero
	CALL	OUTPUT		; Flush the buffer so form feed is done
	RETURN


	.SBTTL	OPRWAT -- PROMPT OPERATOR WITH MESSAGE
;								
;	routine to prompt operator and wait for signal to
;	continue
;
;	The first page is a special case.
;
OPRWAT::SAVE	R0,R1,R2,R3	; Save my registers
	BITEQ	#PAUSW,$OUSW,90$ ; don't wait for new paper?
	CALL	OUTPUT		; Flush the buffers.
	CALL	TFOUT		; TOC buffer as well.
	MOVB	CHPTN,R0	; Get low chapter number.
	CMP	R0,LOWCHP	; In range?
	BLO	90$		; No
	CMP	PAGENO,LOWPAG	; Compare low page number.
	BLO	90$		; Not in range.
	SUB	#6*2,SP		; get scratch area
	MOV	SP,R0		; point to it -> r0
	SUB	#6*2,SP		; get another block
	MOV	SP,R1		; point to it in r1
	GLUN$S	#OUTLUN,R0	; get lun info
	BITEQ	#UC.OSP,G.LUCW(R0),10$ ; is it output spooled ?
	DIAG	IASSP1		; ias intercept spooling doesn't
				; allow /wa to work.
	BR	40$		; and leave

10$:	BITEQ	#UC.DIR!UC.SDI,G.LUCW(R0),15$
	DIAG	IASSP3		; invalid output device
	BR	40$		; and leave

15$:	GLUN$S	#MSGLUN,R1	; get lun info
	BITNE	#UC.TTY,G.LUCW(R1),20$ ; is ti: device a terminal
	DIAG	IASSP2		; ti device invalid
	BR	40$		; and leave
	
20$:	TSTB	$OPFLG		; Has a message been done yet ?
	BNE	26$		; NE - yes
	INCB	$OPFLG		; Set flag
	DIAG	MGWIGL		; wake the operator up

26$:	QIOW$S	#IO.RVB,#MSGLUN,#1,#100.,R1,#0,<R0,#6*2,#0> ; wait for operator
	BCS	40$
	CMPNE	(R1),#IE.EOF,50$ ; ^z means to inhibit wait

40$:	BIC	#PAUSW,$OUSW	; clear wait state

50$:	ADD	#6*4,SP		; clean stack
90$:	UNSAVE	R0,R1,R2,R3
	RETURN			; return

;
; start of runoff
;

START:	JMP	$START		;

	.END START
