	.TITLE RNCMD
	.IDENT	/BL3.0/

;
;
; Dec assumes no responsibility for the use or reliability of this
; software.
;
;
; Original AUTHOR: L. WADE 1-JUN-72
;
; MODIFIED BY:
;
;	E. POLLACK U. OF W. 19-DEC-73
;
;	D. N. CUTLER 27-JUL-75
;
;								AZ (new)
;	NSWC Changes:						     V
;
;		10 Feb 87 - Process .TWO PASSES command.
;		 1 Dec 87 - Make .BLANK work right at very bottom of page.
;		 8 Feb 88 - Make lower .PAGE SIZE limit 16 as documented.
;			    Process .ENABLE EMPTY and .DISABLE EMPTY
;			     commands.
;		 5 Apr 88 - Make .PAGE ODD and .PAGE EVEN work correctly
;			     with .ENABLE EMPTY in effect.
;			    Process .FINAL EJECT and .NO FINAL EJECT com-
;			     mands.
;
;								     ^
;								AZ (new)
; RUNOFF COMMANDS
;
;
; CHANGES BY J. CLEMENT		AUGUST 1982
;	ADD  EXTRA FLAGS (SPACE,ACCEPT...)
;	MAKE ALL ENABLE/DISABLE COMMANDS THE SAME LOGIC
;	Lots of new commands added
;
;
;	ALL COMMAND ROUTINES ARE ENTERED WITH:
;
;	R4=ADDRESS OF NUMBER CONVERSION ROUTINE.
;	R5=SW.DIS
;

	.vars
ADDR:	.BLKA	1
COUNT:	.BLKA	1
STAT:	.BLKA	1
	.CODE
;
;	PERIOD commands
;
PERSP::	BISB	R5,$PERSW	; ENABLE TWO SPACES AFTER PUNCTUATION
	MOV	#CH.PER,R5	; Bits to set/clear
PERSET:	CALL	GETLIT		; Get literal
	BCS	30$		; None ?
	TSTEQ	R1,30$		; No characters ?
20$:	MOVB	(R0)+,R2	; Get character
	MOV	R2,R0
	ADD	#CHTABL,R0
	BISB	R5,(R0)		; Set the bit
	SOB	R1,20$		; Continue till done
30$:	RETURN			; 
;
;	NO PERIOD command
;
NPERS::	BICB	R5,$PERSW	; DISABLE TWO SPACES AFTER PUNCTUATION
	MOV	#CH.PER,R5	; Bits to set/clear
PERCLR:	CALL	GETLIT		; Get literal
	BCS	30$		; None ?
	TSTEQ	R1,30$		; No characters ?
20$:	MOVB	(R0)+,R2	; Get character
	MOV	R2,R0
	ADD	#CHTABL,R0
	BICB	R5,(R0)		; Set the bit
	SOB	R1,20$		; Continue till done
30$:	RETURN			; 
;
;	ENABLE/DISABLE CHANGE BAR COMMADS (ALSO ON AND OFF)	
;
ENCBR::	BICB	R5,$CBRSW	; ENABLE BAR
	CALL	(R4)		; Get first indent
	CMP	R3,#10.		; Test size
	BHI	20$		; Too big ?
	MOV	R3,EBSIZ1	; First indent
	CALL	(R4)		; Second indent
	BCC	2$		; Number ?
	  MOV	#CBNSP,R3	; Default second offset
2$:	CMP	R3,#10.		; Test size
	BHI	20$		; Too big ?
	MOV	R3,EBSIZ2
	CALL	GETLIT		; Get literal
	BCS	10$		; None ?
	MOVB	#BAR,CHBAR	; Set default char
	TSTEQ	R1,10$		; No char spec ?
	MOVB	(r0),CHBAR	; New char
10$:	RETURN
20$:	MOV	#4.,R0		; Param too big or negative
	JMP	ILCMA
DSCBR::	BISB	R5,$CBRSW	; DISABLE BAR	
	RETURN
ENBAR::	BISB	#SW.TDS,$CBRSW	; BAR OFF	
	RETURN						
BGBAR::	BICB	#SW.TDS,$CBRSW	; BAR On
	RETURN
;
;	ENABLE CONTINUE
;
ENCONT::BICB	R5,$CONT	; Enable continue
	RETURN
DSCONT::BISB	R5,$CONT	; Disable continue
	RETURN
;
;	KEEP LINES command
;	KEEP TABS command
;
KEEPL::	BISB	R5,$KEEPL	; Enable keep lines
	RETURN
NKEEPL::BICB	R5,$KEEPL	; Disable keep lines
	RETURN
KEEPT::	BISB	R5,$KEEPT	; Enable keep tabs
	RETURN
NKEEPT::BICB	R5,$KEEPT	; Disable keep tabs
	RETURN
;							
;	AUTOPARAGRAPH commands
;
AUTOP::	MOVB	#-1,$AUTSW	; SET AUTOPARAGRAPH MODE
	RETURN			;
NAUTO::	CLRB	$AUTSW		; CLEAR AUTOPARAGRAPH MODE
	RETURN			;
AUTTB::	MOVB	#1,$AUTSW	; Set autotable mode
	RETURN
;
;	AUTOHYPHENATE commands
;
AUHYP::	BICB	R5,$AUHYP	; Set autohyphenate enabled
	CALL	(R4)		; Get initial char count
	BCS	10$		; None ?
	MOV	R3,HYPSZ	; Char saved ?
10$:	CALL	(R4)		; Get initial char count
	BCS	20$		; None ?
	MOV	R3,HYPLO	; Initial char count
20$:	CALL	(R4)		; Get Final char count
	BCS	30$		; None ?
	MOV	R3,HYPHI	; Final char count
30$:	CALL	(R4)		; Get Option
	BCS	40$		; None ?
	MOVB	R3,HYPOP	; Save hyphenation option
40$:	MOV	HYPLO,R0	; Get lo value
	ADD	HYPHI,R0	; Add on final char count
	CMP	R0,HYPSZ	; Greater than current size ?
	BLE	50$		; No ?
	MOV	R0,HYPSZ	; Save it
50$:	MOV	#CH.PNC,R5	; Set up punctuations
	JMP	PERSET
NAUHYP:: BISB	R5,$AUHYP	; Set autohyphenate disabled
	MOV	#CH.PNC,R5	; Set up punctuations
	JMP	PERCLR
;
;	ELLIPSES commands
;
ELIPS::	BISB	R5,$ELIPS	; Set ellipses flag
	RETURN
NELIP::	BICB	R5,$ELIPS	; Clear ellipses flag
	RETURN
;
;	TAB RIGHT command
;	TAB LEFT command
;
TABRI::	BISB	R5,$TABLF	; Set up for right justify tabs
	RETURN
TABLF::	BICB	R5,$TABLF	; Left justify tabs
	RETURN
;
;	ENABLE/DISABLE commands
;
;		0=ENABLED	NONZERO=DISABLED
;
ENESC::	BICB	R5,$ESCSW	; ENABLE ESCAPE SEQ.
	RETURN
DSESC::	BISB	R5,$ESCSW	; DISABLE ESCAPE SEQ.
	RETURN
ENSUB:: BICB	R5,$SUBSW	; enable substitution
	RETURN
DSSUB:: BISB	R5,$SUBSW	; disable substitution
	RETURN
ENTAB::	BICB	R5,$TABSW	; Enable tabs
	RETURN
DSTAB::	BISB	R5,$TABSW	; Disable tabs
	RETURN
ENUNL::	BICB	R5,$UNLSW	; ENABLE UNDERLINE SEQ.
	RETURN
DSUNL::	BISB	R5,$UNLSW	; DISABLE UNDERLININE 
	RETURN
ENOVR::	BICB	R5,$OVRSW	; ENABLE OVERSTRIKING
	RETURN
DSOVR::	BISB	R5,$OVRSW	; DISBLE OVERSTRIKING
	RETURN
ENHYP::	BICB	R5,$HYPSW	; ENABLE HYPHENATION
	RETURN
DSHYP::	BISB	R5,$HYPSW	; DISABLE HYPHENATION
	RETURN
ENINX::	BICB	R5,$INXSW	; ENABLE INDEXING
	RETURN
DSINX::	BISB	R5,$INXSW	; DISABLE INDEXING
	RETURN
;
;	INDENT command
;
INDENT::TSTEQB	$CENSW,10$	; No Centering ?
	JMP	ERRCON		; Conflicting command
10$:	CALL	(R4)		; READ SIGNED DECIMAL NUMBER
	BCC	INDCK		; Params ?
	  MOV	PARIND,R3	; NONE. USE CURRENT VALUE
INDCK:	MOV	LMARG,R0	; Compare if legit
	NEG	R0		; 
	TSTNEB	$RIGSW,10$	; Right margin ?
	CMP	R3,R0
	BGE	10$		; Greater than left
	JMP	ERRLT		; Yes!
10$:	SUB	R3,R0		; Is it less than left margin
	ADD	RMARG,R0	; Space available
	CMP	R0,#MINLN	; Now compare with line minimum
	BGE	15$		; Indent Not too big ?
	JMP	ERRGT		; Indent too big ?
15$:	CMP	R0,#255.	; Compare with max char per line
	BLOS	20$		; Small enough ?
	JMP	ERRHI		; Indent too small
20$:	MOV	R3,INDCT	; Save indentation
	RETURN
;
;	TOP MARGIN command
;
SETTM::	MOV	TMARG,R3	; GET CURRENT TOP MARGIN
	CALL	(R4)		; GET RELATIVE ARGUMENT
	BCS	10$		; Take default
	CALL	CVSP		; Convert to half spacing
	BR	20$		; Now check it
10$:	MOV	PTMRG,R3
20$:	ADD	#MINPG,R3	; MINPG lines minimum on page
	CMP	R3,PNLPG	; MUST BE LESS THAN PAGE LENGTH?
	BLE	30$		; Is it less than page ?	; AZ (was BLT)
	JMP	ERRGT		; IF GE NO
30$:	SUB	#MINPG,R3	; TAKE DEMANDED LINE OUT
	MOV	R3,TMARG	; OK SAVE AS TOP MARGIN
	RETURN			; 
;
;	LEFT MARGIN command
; 
SETLM::	MOV	LMARG,R3	; GET CURRENT LEFT MARGIN
	CALL	(R4)		; GET RELATIVE ARGUMENT
	BCC	1$		; Number ?
	  MOV	PLMRG,R3	; IF NONE, INITIALIZE
1$:	ADD	#MINLN,R3	; Add on minimum line length
	CMP	R3,RMARG	; MUST BE LESS THAN RIGHT MARGIN?
	BLE	20$		; Less than right margin ?	; AZ (was BLT)
	JMP	ERRGT		; IF GE NO
20$:	SUB	#MINLN,R3	; Restore
	MOV	R3,LMARG	; OK SAVE AS LEFT MARGIN
	RETURN			; 
;
;	RIGHT MARGIN command
;
SETRM::	MOV	RMARG,R3	; GET CURRENT RIGHT MARGIN
	CALL	(R4)		; GET RELATIVE ARGUMENT
	BCC	1$		; Number ?
	  MOV	PRMRG,R3	; IF NONE, INITIALIZE
1$:	SUB	#MINLN,R3	; Subtract min line length
	CMP	R3,LMARG	; MUST BE RIGHT OF LEFT MARGIN
	BGE	20$		; Greater than left
	JMP	ERRLT		; IF GT OKAY
20$:	ADD	#MINLN,R3	; Restore
	MOV	R3,RMARG	; SAVE IT
	RETURN
;
;	 STANDARD command
;
STAND::	MOV	#ISPNG*LINSP,NSPNG; SET STANDARD SPACING
	MOV	#ILMRG,	LMARG	; INITIALIZE LEFT MARGIN
	MOV	#ITMRG, TMARG	; TOP MARGIN	
	MOV	#IRMRG, RMARG	; RIGHT MARGIN	
	MOV	IPARIN,PARIND	; SET INITIAL PARAGRAPH INDENT
	MOV	#INLPG*LINSP,R3	; SET INITIAL PAGE LENGTH PARAMETER
	BIS	#FILLF!JUSTF!PJUSTF,F.1 ;SET TO FILL AND JUSTIFY
	BR	SETPG1		; FINISH IN COMMON CODE
;
;	PAGE SIZE command
;
SETPG::	BICB	#SW.TDS,$PAGNG	; Enable paging
	MOV	PNLPG,R3	; GET CURRENT PAGE LENGTH
	CALL	(R4)		; GET RELATIVE ARGUMENT
	BCS	10$		; Take default
	CALL	CVSP		; Convert to half spacing
	CMP	R3,#MINPG	; LONG ENOUGH TO BE REASONABLE	FOR HEADING
	BGE	5$		; OK ?				; AZ (was BGT)
	JMP	ERRLT		; Too small ?
5$:	CMP	R3,#255.	; Check max size
	BLE	SETPG1		; Not too small ?
	JMP	ERRGT		; Too big ?
10$:	MOV	PNLPG,R3	; Default to current length
SETPG1:	MOV	R3,NLPG		; SAVE AS LENGTH OF THIS PAGE
	MOV	R3,PNLPG	; AND PERMANENT PAGE LENGTH
	CALL	SETRM		; SET RIGHT MARGIN
	MOV	R3,PRMRG	; SET NEW PERMANENT MARGIN
	CALL	SETLM		; GET LEFT MARGIN
	MOV	R3,PLMRG	; SET PERMANENT LEFT
	CALL	SETTM		; GET TOP MARGIN
	MOV	R3,PTMRG	; SET PERMANENT TOP
	CALL	SSP		; Set permanent spacing
	MOV	R3,PSPNG	; Save permanent spacing
	RETURN			; 
;
;	The error returns
;
ERRGT:	MOV	#1,R0		; Param too big
	BR	ERR
ERRLT:	MOV	#2,R0		; Param too small
	BR	ERR
ERRHI:	MOV	#8.,R0		; Param too big or negative
	BR	ERR
ERRCON:	MOV	#43.,R0
ERR:	JMP	ILCMA		; Output the message
;
;	SET PARAGRAPH command
;
SETPR::	MOV	#PARIND,R5	; Address of paragraph variables
	CALL	(R4)		; OPTIONAL IDENTING ARGUMENT
	BCC	1$		; Number ?
	  MOV	PARIND,R3	; NO. USE OLD VALUE
1$:	MOV	RMARG,R1	; Get line size
	SUB	LMARG,R1
	CMP	R3,R1		; REASONABLE VALUE?
	BLE	5$		; Is it less than line size ?
	JMP	ERRGT		; IF GT NO
5$:	MOV	R3,(R5)+	; STORE PARA INDENT VALUE
	CALL	10$
	CALL	10$
	CALL	10$
	RETURN
10$:	CALL	(R4)		; GET COUNT
	BCC	11$		; Number ?
	  MOV	(R5),R3		; Default
11$:	CMP	R3,#MAXPS	; Within reason ??
	BLOS	20$		; Is it small enough, non neg ?
	JMP	ERRHI
20$:	MOV	R3,(R5)+	; Save the value
	RETURN
;
;	HALF SPACING command
;
NHSPSW:: BISB	R5,$HSPSW		; Disable half spacing
	RETURN
HSPSW:: BICB	R5,$HSPSW		; Enable half spacing
;
;	SPACING command
;
SSP::	CLR	R3		; No initial value
	CALL	(R4)		; GET ARGUMENT OF SPACING command
	BCS	10$		; Take default
	CALL	CVSP		; Convert to half spacing
	CMP	R3,#MAXPS*LINSP	; MUST BE IN RANGE 1 to max paragraph spacing
	BLE	5$		; Is it small enough ?
	JMP	ERRGT
;5$:	CMP	R3,#LINSP	; Must be at least 1 line
5$:	TST	R3		; Is it non negative
	BGE	20$		; Is it OK ?
	JMP	ERRLT		; Zero or negative ?
10$:	MOV	PSPNG,R3	; Restore permanent spacing
20$:	MOV	R3,NSPNG	; OK. STORE AS NORMAL SPACING
	RETURN			; 
;
;	PARAGRAPH command
;
PARAG::	CALL	SETPR		; GET PARAMS
	JMP	PARTP		; And do the paragraph

;
;	TEST TEXT command
;
TSTTX::	CALL	10$		; Get top test
	MOV	R1,R5		; Save value
	CALL	10$		; Bottom test
	MOV	R1,R4		; Bottom test
	JMP	PARTS		; Now test the arguments
10$:	CALL	(R4)		; Get argument
	BCC	11$		; Number ?
	  MOV	#1,R3		; Default if no argument
11$:	MOV	R3,R1		; Number to mul
	CALL	MULSP		; Find actual adjusted line spacing
	RETURN
;
;	TEST PAGE command
;
TSTPG::	CALL	(R4)		; GET ARGUMENT OF TEST
	BCC	10$		; Number ?
	  MOV	#1,R3		; Default
10$:	CALL	CVSP		; Convert to half spacing
	MOV	R3,R5		; Save result
	CALL	(R4)		; GET ARGUMENT OF TEST
	CALL	CVSP		; Convert to half spacing
	MOV	R3,R4
	JMP	PARTS		; Now test the params
;
;	SKIP command
;
SKIP::	CALL	(R4)		; GET OPTIONAL ARGUMENT
	BCC	1$		; Number ?
	  MOV	#1,R3		; IF NONE, ASSUME 1
1$:	MOV	R3,R1		; Set up to multiply lines x line spacing
	CALL	MULSP		; Find actual adjusted line spacing
	MOV	R1,R2
	BR	LINSK1
;
;	BLANK command
;
LINSKP:: CALL	(R4)		; GET OPTIONAL ARGUMENT
	BCC	1$		; Number ?
	  MOV	#1,R3		; IF NONE, ASSUME 1
1$:	CALL	CVSP		; Convert to half spacing
	MOV	R3,R2		; Skip count
LINSK1:	CMP	R2,#255.	; Check size
	BLE	10$
	JMP	ERRGT
10$:	TSTNEB	$PAGNG,11$	; No paging
	BITEQ	#FOTF,F.1,15$	; Not currently footnote ?
11$:	CMP	R2,#MAXPS*LINSP	; Max if footnote
	BLOS	30$		; Ok?
	JMP	ERRHI		; No
15$:	BITNE	#TEXF,F.1,30$	; text ?
	TST	R2		; CHECK IF ARGUMENT IS NEG
	BLT	20$		; IF NEGATIVE DO NOT MAKE TOP OF PAGE CHECK
	TSTEQB	$PAGBR,50$	; AT TOP OF PAGE?
	BR	30$
20$:	ADD	LINEC3,R2	; Skip from bottom
25$:	BGT	45$		; Ok ?
	MOV	#LINSP,R2	; ELSE JUST SKIP 1 LINE	
30$:	TSTNEB	$PAGNG,45$	; No paging ?
	TSTB	$PFOOT		; Permanent footnote in progress?
	BLT	45$		; Yes
	CMP	R2,LINEC3	; Test room on page
	BLE	40$		; Room still left ?
	MOV	R2,-(SP)	; Save skip
	CALL	BPAGE		; No! make a new page
	MOV	(SP)+,R2	; Restore
40$:	BIS	#SW.NEG,R2	; Mark it as optional skip
45$:	JMP	SKPNIF		; YES. SPACE OUT C(R2) LINES	! AZ (was SKIPN)
50$:	RETURN			; 
;
;	FIGURE command
;
FIGUR::	CALL	(R4)		; GET ARGUMENT
	BCC	1$		; Number ?
	  MOV	#1,R3		; IF NONE, ASSUME ONE LINE
1$:	CALL	CVSP		; Convert to half spacing
10$:	CMP	R3,#255.	; Check size
	BLOS	11$
	JMP	ERRHI
11$:	MOV	R3,-(SP)	; SAVE DESIRED SPACE
	MOV	R3,R1
	CALL	TESTP		; TEST IF PAGE SHOULD BE BROKEN
	MOV	(SP)+,R2	; GET BACK DESIRED SIZE
	JMP	SKIPN		; SPACE THAT OUT
;
;	FIGURE DEFERRED command
;
FIGDF::	CALL	(R4)		; GET ARGUMENT
	BCC	1$		; Number ?
	  MOV	#1,R3		; IF NONE, ASSUME ONE LINE
1$:	CALL	CVSP		; Convert to half spacing
10$:	CMP	R3,#255.	; Check size
	BLOS	11$
	JMP	ERRHI
11$:	MOV	R3,-(SP)	; Save
	CALL	TEXTD
	MOV	(SP)+,R2	; Get skip count
	CALL	SKIPN		; Skip lines
	JMP	ENTEX
;
;	FILL/JUSTIFY commands
;
JUSTN::	BIS	#JUSTF+PJUSTF,F.1 ;TURN ON JUSTIFYING
	RETURN			; 
JUSOF::	BIC	#PJUSTF+JUSTF,F.1 ;TURN OFF JUSTIFY BITS
	RETURN			; 
FILLN::	BIS	#FILLF+JUSTF,F.1 ;TURN ON FILLING, COPY PJUSTF TO JUSTF
	BITNE	#PJUSTF,F.1,10$ ;COPY PERMANENT FLAG
	BIC	#JUSTF,F.1	; TO CURRENT ONE.
10$:	RETURN			; 
FILOF::	BIC	#FILLF+JUSTF,F.1 ;TURN OFF FILLING AND JUSTIFYING
	RETURN			; 

;
;	TAB STOPS command
;
SETTAB::MOV	#TABBF,R3	; Tab buffer
	CALL	CLRBF		; CLEAR NUMBER OF TABS
	CLR	R5		; Set up test value
	MOV	LMARG,R4	; Initial starting point
10$:	CALL	TABPRE		; Get Pretab chars
	BCS	15$		; null param
	MOV	R4,R3		; Default stop
	CALL	RCNR		; GET ANOTHER STOP IF ANY
	BCC	16$		; Found one ?
15$:	  RETURN		; 
16$:	MOV	R3,R1		; Get value
	CMP	R1,R5		; Too small?
	BLE	20$		; Yes
	MOV	R1,R5		; Save comparison
	MOV	#TABBF,R3	; Tab table to save tabs
	CALL	PWRD		; Save a tab
	CALL	TABPOS		; Now save status
	MOV	R5,R4		; New default value
	BR	10$
20$:	JMP	ILCM		;
TABPOS:	MOVB	STAT,R1		; status
	ADD	COUNT,R1	; Plus count
	CALL	PBYT		; To buffer
	TSTEQ	COUNT,20$	; No count ?
	MOV	ADDR,R0		; Address of String to transfer
	CALL	PSTRZB		; Transfer it
20$:	RETURN
TABPRE:	CLR	COUNT		; Set no count
	CALL	GETLIT		; Get literal
	BCS	10$		; None ?
	MOV	R0,ADDR
	MOV	R1,COUNT
	CMP	R1,#TB.CNT-1	; Is it too big ?
	BHI	40$		; Yes
10$:	CLR	R3		; No default params
	CLRB	STAT		; No status
	CALL	ALPGT		; Get alpha input
	BCS	35$		; None
	CMPNE	R3,#^o14,20$	; Is it "L" ?
	BISB	#TB.L,STAT	; Yes
	BR	35$
20$:	CMPNE	R3,#^o22,30$	; Is it "R" ?		
	BISB	#TB.R,STAT	; Yes
	BR	35$
30$:	CMPNE	R3,#^o3,31$	; Is it "C" ?		
	BISB	#TB.C,STAT	; Yes
	BR	35$
31$:	TSTNE	R3,40$		; Is it OK ?
	SEC
	BR	36$
35$:	CLC
36$:	RETURN			; Yes
40$:	JMP	ILCM
;
;	TAB PROPORTIONAL command
;
TABPR::	MOV	#TABBF,R3	; Tab buffer
	CALL	CLRBF		; Cleared
	CALL	(R4)		; Get proportion
	BCC	2$		; Parameter ?
1$:	  RETURN		; Default is no columns
2$:	MOV	R3,R5		; Number of tabs
	BLE	1$		; Too small
	MOV	RMARG,-(SP)	; Get right margin
	SUB	LMARG,(SP)	; Minus the left
	CLR	R2		; Number of default tabs
10$:	CALL	TABPRE		; Get stuff in front of tab
	BCS	12$		; Null entry ?
	CALL	RCNO		; Get tab
	BCC	13$		; Not Null entry ?
12$:	MOV	#1,R1		; Set +-
13$:	ASL	R3		; Multiply by 2
	BVC	14$		; No overflow
	BR	61$		; Overflow ?
14$:	TSTEQ	R1,15$		; Not + or -
	INC	R2		; Count relative params
	INC	R3		; Set +- bit
15$:	MOV	R3,R1
	MOV	#TABBF,R3	; Buffer to sav in
	CALL	PWRD		; Save tab magnitude
	ASR	R1		; Strip out carry
	SUB	R1,(SP)
	BGT	155$
	BR	61$		; Stop too big ?
155$:	CALL	TABPOS		; Add on status
	SOB	R5,10$		; Continue ?
	MOV	(SP)+,R1	; Number of spaces left
	TSTEQ	R2,16$		; No default tabs ?
	DIV$	R2,R1		; Divide spaces left by default tabs
	MOV	R1,R2		; Save remainder
	MOV	R0,R5		; Save field width
16$:	MOV	LMARG,R4	; Get current left margin
;
;	Now set up tab loop
;
	MOV	#TABBF,R3	; Get tab buffer
	CALL	BEGBF		; Start at beginning
20$:	MOV	BF.FUL(R3),-(SP); Save current index
	CALL	GWRD		; Get entry
	BCS	50$		; Done ?
	.if df	$VMS
	.if ndf	$LONG
	CVTWL	R1,R1
	.endc
	.endc
	BITNE	#1,R1,30$	; Test +- bit is it - ?
	ASR	R1		; Get tab
	BR	40$		; Fixed field width ?
30$:	ASR	R1		; Get width
	ADD	R5,R1		; Add on field width
	DEC	R2		; Check remainder
	BLT	40$		; None left ?
	INC	R1		; Add 1 to stop
40$:	TST	R1		; Check field
	BLE	61$		; Not Big enough ?
	ADD	R1,R4		; Add to current position
	MOV	(SP)+,R1	; Get index this word
	CALL	FNDBF		; Go back
	MOV	R4,R1		; To be saved
	CALL	PWRD
	CALL	GBYT		; Get status
	BIC	#^C<TB.CNT>,R1	; Strip it
	ADD	BF.FUL(R3),R1	; Next location
	CALL	FNDBF		; Get it
	BR	20$
50$:	TST	(SP)+		; Pop index
	RETURN
61$:	MOV	#TABBF,R3
	CALL	CLRBF		; Clear out bad tabs
	JMP	ILCM		; Value too small
;
;	Break line command
;
BRKLN::	BISB	#SW.TDS,$BRKSW	; Set to break line
	RETURN
;
;	CENTER command
;
CENTER:: MOV	#SW.TDS,R5	; Set up temporary center this line
CENTRT:: TSTNE	INDCT,5$	; Currently set indentation ?
	TSTEQB	$RIGSW,10$	; Not right justified ?
5$:	JMP	ERRCON
10$:	BISB	R5,$CENSW	; CENTER LINES TILL END
	MOV	RMARG,R3	; RIGHT
	ADD	LMARG,R3	; PLUS LEFT
	CLC
	ASR	R3		; DIVIDED BY 2
	MOV	R3,CMARG	; DEFAULT
	CALL	(R4)		; GET RELATIVE ARG
	BCC	1$		; Number ?
	  MOV	CMARG,R3	; DEFAULT
1$:	MOV	R3,CMARG	; CENTERING MARGIN
	RETURN
;
;	END CENTER command
;	END RIGHT command
;
ECENT::	BICB	R5,$CENSW	; CLEAR CENTERIN SWITCH
ERIGHT::BICB	R5,$RIGSW	; Reset permanent right shift
	CLR	INDCT
	RETURN
;
;	RIGHT command
;	RIGHT TEXT command
;
RIGHJ::	MOV	#SW.TDS,R5	; Set temporary righj justify switch
RIGHT::	TSTEQB	$CENSW,10$	; Not centered justified ?
	JMP	ERRCON
10$:	BISB	R5,$RIGSW	; Set permanent right justify switch
	CALL	(R4)		; Get shift
	JMP	INDCK		; Check indent
;
;	PERMANENT FOOTNOTE command
;
PERFN::	TSTNEB	$PAGNG,ILLEG	; No paging ?
	TSTNEB	$FOTPD,10$	; Footnote pending?
	MOVB	#-1,$PFOOT	; Indicate permanent footnote
	MOV	#FOTBF,R3	; Get footnote buffer
	CALL	CLRBF		; Clear it
	CLR	FOTLN		; Clear number of lines of footnote
	CLR	PFOTHD		; Clear permanent footnote header
	BR	FOOT1		; Do not set pending
10$:	MOV	#33.,R0		; Can't do permanent footnote
	JMP	ILCMA
ILLEG:	JMP	ILCM
;
;	FOOTNOTE command
;
FOOTN::	TSTNEB	$PAGNG,ILLEG	; No paging ?
	TSTNEB	$FOTPD,10$	; No footnote pending?
	DECB	$FOTPD		; Footnote now pending
	SUB	FOTLN,LINEC3	; Test if enough room
	MOV	FOTLN,FOTBF+BF.VSP	; Set up footnote size
10$:	MOV	NSPNG,R1	; Number of blanks/line
	CALL	TESTP		; Test it
FOOT1:	MOV	#FOTSV,R0	; FOOTNOTE SAVE BUFFER
	MOV	#SAVBEG,R1	; PARAMS TO SAVE
	MOV	#SAVSZ,R2	; SIZE OF SAVE BUFFER
10$:	MOVB	(R1)+,(R0)+	; SAVE EM
	SOB	R2,10$		; TILL DONE
	CLR	INDCT		; CLEAR INDENTATION
	TSTB	$PFOOT		; Permanent params?
	BLE	30$		; No ?
	MOV	#PFTSV,R0	; Footnote permanent save buffer
	MOV	#PFSBEG,R1	; Table to restore
	MOV	#PFSIZ,R2	; # of bytes to save
20$:	MOVB	(R0)+,(R1)+	; SAVE EM
	SOB	R2,20$		; TILL DONE
30$:	BIS	#FOTF,F.1	; PUT OUTPUT INTO FOOTNOTE BUFFER
	RETURN			; 
;
;	END FOOTNOTE
;
FOOTE::	BITEQ	#FOTF,F.1,20$	; Footnote not in progress?
	CALL	OUTAD		; Get footnote buffer
	TSTB	$PFOOT		; Permanent footnote in progress?
	BGE	5$		; No?
	MOV	BF.VSP(R3),R0	; Get footnote size
	CMP	R0,#12.		; Check size
	BLOS	1$		; OK ?
	CALL	CLRBF		; Clear the footnote buffer
	MOV	#ILCMA,-(SP)	; How to end
1$:	MOVB	#1,$PFOOT	; Set not in progress, but on
	MOV	BF.VSP(R3),FOTLN; Save permanent footnote size
	MOV	BF.FUL(R3),PFOTHD; Save header address
	MOV	#PFTSV,R0	; Footnote permanent save buffer
	MOV	#PFSBEG,R1	; Table to save
	MOV	#PFSIZ,R2	; # of bytes to save
3$:	MOVB	(R1)+,(R0)+	; SAVE EM
	SOB	R2,3$		; TILL DONE
5$:	MOV	#FOTSV,R0	; FOOTNOTE SAVE BUFFER
	MOV	#SAVBEG,R1	; PARAMS TO RESTORE
	MOV	#SAVSZ,R2	; SIZE OF SAVE BUFFER
10$:	MOVB	(R0)+,(R1)+	; RESTORE EM
	SOB	R2,10$		; TILL DONE
	MOV	#47.,R0		; Error message
	RETURN			; 
20$:	MOV	#28.,R0		; Unexpected END FOOTNOTE
	JMP	ILCMA		; Output error message
;
;	TEXT commands
;
TEXTC::	TSTNEB	$PAGNG,TXRET	; No paging ?
	CALL	ENTEX		; Output previous text
	TSTEQB	$PAGBR,TXRET	; Already at top of page?
	BIS	#TEXF,F.1	; Deferred text flag
TXRET:	RETURN
;
;	END TEXT command
;
ENTEX::	TSTNEB	$PAGNG,TXRET	; No paging ?
	TSTNEB	$SBPSW,ERRSBP	; Subpage ?
	BITEQ	#TEXF,F.1,TXRET	; Not in text mode ?
	BITNE	#TXDEF,F.1,10$	; Currently text deferred ?
	BIC	#TEXF,F.1	; No longer
	JMP	OUTNJ		; Now output the text
10$:	CALL	TXDEND		; End the deferred text
	CALL	TXDOUT		; And any deferred text
	RETURN			; 
ERRSBP:	MOV	#37.,R0		; Illegal during subpage
	JMP	ILCMA
;
;	TEXT DEFERRED command
;
TEXTD::	TSTNEB	$PAGNG,10$	; No paging ?
	CALL	ENTEX
	TSTEQB	$PAGBR,10$	; Already at top of page?
	BIS	#TXDEF!TEXF,F.1	; Set up for deferred text
	MOV	LINEC3,LN3SAV	; Save current number of lines
	MOV	NLPG,R0		; Number of lines
	SUB	TMARG,R0	; Minus top margin
	BITNEB	#^C<SW.TDS>,$HDRSW,5$	; No header ?
	SUB	#LINSP,R0	; Minus title
	SUB	HSPAC,R0	; Minus subtitle
5$:	SUB	$EOPSP,R0	; Minus space at bottom
	MOV	R0,LINEC3	; Now potential lines
	CALL	OUTAD		; Get buffer address
	CALL	ENDBF		; Go to end of buffer
	CLR	BF.VSP(R3)	; No vertical spacing yet
	MOV	BF.FUL(R3),TXDHED ; Save header
	CALL	CBYT		; Count filled in later
	MOV	#HD.TXD,R1	; Now put text deferred status
	CALL	PBYT		; into buffer
10$:	RETURN
;
;	PAGE command - produces a new page
;
NEWP0:	TSTEQB	$SBPSW,NEWPAG	; Not Subpage ?
	JMP	ERRSBP
NEWPAG::BITEQ	#TEXF,F.1,20$	; NOT in text or text def section ?
	CALL	OUTAD
	MOV	LINEC3,R2	; Skip to end of page
	CALL	SKIPN
	JMP	ENTEX		; End the text section
20$:	BITNEB	#^C<SW.TDS>,$PAGNG,30$	; Paging permanently off ?
	MOVB	$PAGNG,-(SP)	; Save paging status
	CLRB	$PAGNG		; Set paging on
	CALL	CPAGE		; Start new page
	MOVB	(SP)+,$PAGNG	; Restore paging status
30$:	RETURN
;
;	PAGE EVEN command - Produce even numbered page
;
PAGEV::	BITEQ	#1,PAGENO,EMPTY					; AZ 4/88
	JMP	NEWP0						; AZ 4/88
;
;	PAGE ODD command - Produce odd numbered page
;
PAGOD::	BITNE	#1,PAGENO,EMPTY					; AZ 4/88
	JMP	NEWP0						; AZ 4/88
;								; AZ 2/88
EMPTY:	TSTEQB	$SBPSW,1$					; AZ 4/88
	JMP	ERRSBP						; AZ 4/88
1$:	TSTNEB	$EMPSW,2$					; AZ 4/88
	BISB	#SW.TDS,$HDRSW					; AZ 2/88
	BISB	#SW.DIS,$NM2SW					; AZ 2/88
	CALL	NEWP0						; AZ 2/88
	BICB	#SW.DIS,$NM2SW					; AZ 2/88
	JMP	BPAGE						; AZ 4/88
2$:	CALL	NEWP0						; AZ 4/88
	JMP	BPAGE						; AZ 4/88
;
;	ENABLE EMPTY command
;
ENEMP::	BICB	R5,$EMPSW
	RETURN
DSEMP::	BISB	R5,$EMPSW
	RETURN							;           ^
;								; AZ 2/88 (new)
;
;	ENABLE ODD command
;
ENODD::	BISB	#SW.TDS,$ODPAG	; ENable odd pages
	RETURN
DISODD::BICB	#SW.TDS,$ODPAG	; Disable odd pages
	RETURN
;								; AZ 4/88
;	FINAL EJECT and NO FINAL EJECT				;      V
;
FINEJ::	BICB	R5,$EJECT
	RETURN
NFNEJ::	BISB	R5,$EJECT					;      ^
	RETURN							; AZ 4/88
;								; AZ (new)
;	TWO PASSES command					;      V
;
;	This command must be very first one, or results are
;	indeterminate; no diagnostic appears if out of place.
;
TPASS::	BITNE	#PASSW,$SWTCH,10$	; Skip if second pass, or /2PASS,
	BIS	#PASSW,$SWTCH		;  or already did .TWP
	BIS	#SW.DIS,$OUTSW
10$:	RETURN							;      ^
;								; AZ (new)
	.END
