	.TITLE	GCIN
	.IDENT	/V01/
;
;	These are general input/output character interpretation routines
;
	.PSECT	$TEMP,RW,D,OVR,GBL
	.BLKB	1
TBUFF:	.BLKB	SUBMAX+2
	.even
ADDR:	.BLKW	1
	.PSECT	GCTABL,RW,D,GBL
;
;	INPUT CHARACTER PARSING TABLES
;		TO ADD MORE FLAGS THESE TABLES MUST BE CHANGED
;		THE FLAG DEFINITIONS COORESPOND TO THE FLAG SWITCHES
;
GC.UC==0			; Upper case letters
GC.LC==2			; Lower case letters
GC.AFL==4			; Accept flag
GC.CFL==6			; Capitalize flag
GC.UFL==10			; Underline flag
GC.LFL==12			; Lowercase flag
GC.SFL==14			; Uppercase flag
GC.QFL==16			; Quoted space flag
GC.OFL==20			; Overstrike flag
GC.IFL==22			; Index flag
GC.HFL==24			; Hyphenation flag
GC.EFL==26			; Escape flag
GC.SUB==30			; substitute flag
GC.BRK==32			; break flag
GC.NFL==34			; COMMAND FLAG
GC.CR==36			; CARRIAGE RETURN
GC.TAB==40			; tab input char
GC.LF==42			; lin feed input
GC.DIG==44			; digit (0-9)
GC.SPC==46			; space
GC.MSC==50			; MISCELLANEOUS CHARS
GC.SPF==52			; Special flag
GC.EQ1==54			; Equation flags
GC.EQ2==56			; Equation flags
GC.SIX==60			; Subindex flag
GC.PFL==62			; PEriod flag
GO.UNL==-2			; underline 1 char
GO.ESC==-12			; begin escape sequence
GO.QTS==-14			; quoted space output
GO.BS==-16			; backspace output
GO.TAB=-20			; Tab count byte follows
GO.ELP=-22			; Ellipses count follows this
GC.ILL=-24			; illegal character
GO.REP=-26			; Repeat characters
GO.INX=-30			; Index entry
GO.TOC=-32			; TOC entry
GO.PAG=-34			; Page number
;
;	THE FOLLOWING CORRESPOND TO THE ASCII CHARACTERS
;
GCTABL:: .BYTE	GC.ILL,GC.ILL,GC.ILL,GC.ILL,GC.ILL,GC.ILL	; NUL-ENQ
	.BYTE	GC.ILL,GC.ILL,GO.BS				; ACK-BS
	.BYTE	GC.TAB,GC.LF,GC.ILL,GC.ILL			; TAB,LF,VT,FF
	.BYTE	GC.CR,GC.ILL,GC.ILL,GC.ILL			; CR,SO,SI,DLE
	.BYTE	GC.ILL,GC.ILL,GO.PAG,GO.TOC,GC.ILL		; DC1-nak
	.BYTE	GO.INX,GO.REP,GO.TAB,GO.ELP,GC.ILL		; SYN-SUB
	.BYTE	GO.ESC,GO.UNL,GC.ILL,GC.ILL,GC.ILL		; ESC-US
	.BYTE	GC.SPC						; SPACE
	.BYTE	GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC	;  - &
	.BYTE	GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC	; ' - ,
	.BYTE	GC.MSC,GC.MSC,GC.MSC				; - . /
	.BYTE	GC.DIG,GC.DIG,GC.DIG,GC.DIG,GC.DIG		; 0 - 4
	.BYTE	GC.DIG,GC.DIG,GC.DIG,GC.DIG,GC.DIG		; 5 - 9
	.BYTE	GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC ; : - @
	.BYTE	GC.UC,GC.UC,GC.UC,GC.UC,GC.UC,GC.UC		; UPPER CASE
	.BYTE	GC.UC,GC.UC,GC.UC,GC.UC,GC.UC,GC.UC		; UPPER CASE
	.BYTE	GC.UC,GC.UC,GC.UC,GC.UC,GC.UC,GC.UC		; UPPER CASE
	.BYTE	GC.UC,GC.UC,GC.UC,GC.UC,GC.UC,GC.UC,GC.UC,GC.UC	; UPPER CASE
	.BYTE	GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC,GC.MSC	; [ - `
	.BYTE	GC.LC,GC.LC,GC.LC,GC.LC,GC.LC,GC.LC		; LOWER CASE
	.BYTE	GC.LC,GC.LC,GC.LC,GC.LC,GC.LC,GC.LC		; LOWER CASE
	.BYTE	GC.LC,GC.LC,GC.LC,GC.LC,GC.LC,GC.LC		; LOWER CASE
	.BYTE	GC.LC,GC.LC,GC.LC,GC.LC,GC.LC,GC.LC,GC.LC,GC.LC	; LOWER CASE
	.BYTE	GC.MSC,GC.MSC,GC.MSC,GC.MSC			; { - ~
	.BYTE	GO.QTS						; DEL
;
;	CHARACTER DEFINITION TABLE
;
CH.BRK==1			; Char is followed by break
CH.BRB==2			; Char is preceeded by break
CH.FLC==4			; CHAR MAY BE FLAG CHAR
CH.FLG==10			; CHAR IS CURRENTLY FLAG CHAR
CH.PER==20			; CHAR IS PUNCTUATION
CH.VOW==40			; character is a vowel
CH.PNC==100			; char is punctuation (for routine HYPHEN)
CH.UNL==200			; char is not underlinable
CHTABL:: .BLKB	9.			; Nul-BS
	.BYTE	CH.FLC			; Tab
	.BLKB	22.			; LF-US
	.BYTE	CH.PNC!CH.UNL		; "space"
	.BYTE	CH.FLC!CH.PNC!CH.PER	; !
	.BYTE	CH.FLC!CH.PNC		; "
	.BYTE	CH.FLC			; #
	.BYTE	CH.FLC			; $
	.BYTE	CH.FLC			; %
	.BYTE	CH.FLC			; &
	.BYTE	CH.FLC			; '
	.BYTE	CH.FLC!CH.PNC		; (
	.BYTE	CH.FLC!CH.PNC		; )
	.BYTE	CH.FLC			; *
	.BYTE	CH.FLC			; +
	.BYTE	CH.FLC!CH.PNC		; ,
	.BYTE	CH.FLC			; -
	.BYTE	CH.FLC!CH.PER!CH.PNC	; .
	.BYTE	CH.FLC!CH.PNC		; /
	.BLKB	10.						; 0 - 9
	.BYTE	CH.FLC!CH.PER,CH.FLC!CH.PER			; : ;
	.BYTE	CH.FLC,CH.FLC,CH.FLC				; < = >
	.BYTE	CH.FLC!CH.PER,CH.FLC!CH.PNC			; ? @
	.BYTE	CH.VOW,0,0,0,CH.VOW,0,0,0			; A-H
	.BYTE	CH.VOW,0,0,0,0,0,CH.VOW,0			; I-P
	.BYTE	0,0,0,0,CH.VOW,0,0,0				; Q-X
	.BYTE	CH.VOW,0					; Y-Z
	.BYTE	CH.FLC			; [
	.BYTE	CH.FLC!CH.PNC		; \
	.BYTE	CH.FLC			; ]
	.BYTE	CH.FLC			; ^
	.BYTE	CH.FLC			; _ underscore
	.BYTE	CH.FLC			; `
	.BYTE	CH.VOW,0,0,0,CH.VOW,0,0,0			; A-H
	.BYTE	CH.VOW,0,0,0,0,0,CH.VOW,0			; I-P
	.BYTE	0,0,0,0,CH.VOW,0,0,0				; Q-X
	.BYTE	CH.VOW,0					; Y-Z
	.BYTE	CH.FLC,CH.FLC,CH.FLC,CH.FLC			; { - ~
	.BYTE	CH.PNC						; DEL
	.even
	.psect	$TABL,RO,D,LCL,CON
BITABL:: .WORD	1,2,4,10,20,40,100,200,400
	.WORD	1000,2000,4000,10000,20000,40000,100000
	.PSECT	TEXT,RO,D,LCL,CON
ILSBCM:	.ASCIZ	/RNO -- Unrecognized command/
ILSBST:	.ASCIZ	/RNO -- Too many nested substitutions/
ILSBND:	.ASCIZ	/RNO -- Undefined substitution/
ILUNES:	.ASCIZ	/RNO -- Undefined escape seq./
EQER3:	.ASCIZ	/RNO -- Too many nested fractions/
EQER4:	.ASCIZ	/RNO -- Syntax error in equation/
	.even
	.PSECT	$CODE,I,RO,LCL,CON
;
;	THE JUMP TABLE TO PARSE CHARS
;
	.WORD	HLTER,GOPAG,GOTOC,GOINX,GOREP,HLTER,GOELP,GOTAB
	.WORD	GOBS,GOQTS,GOESC,HLTER,HLTER,HLTER,GOUNL
GCJMP:	.WORD	GCDN,GCUP,GCACC,GCCAP
	.WORD	GCUNL,SHFDN,SHFUP,GCQTS
	.WORD	GCOVR,GCIFL,GCHYP,GCESC
	.WORD	GCSUB,GCBRK,GCINR,GCCR
	.WORD	GCTAB,GCLF,GCINR,GCSPC
	.WORD	GCINR,GCSPF,GCEQN1,GCEQN2
	.WORD	GCSIX,GCPER
;
;	GET INPUT CHARACTER FROM SOURCE FILE AND INTERPRET IT
;		All registers except for R3 are destroyed
;
GCIN::	CALL	CCIN		; GET CHARACTER FROM FILE.
GCIN1:	MOVB	GCTABL(R1),R0	; GET CHARACTER TYPE
DSPTCH:	JMP	@GCJMP(R0)	; DISPATCH ACCORDING TO TABLE
;
;	HERE ARE SPECIAL CHARACTER CASES
;
;	UPPER CASE
GCDN:	TSTB	CASE		; CONVERSION NECESSARY
	BGE	GCINR		; NO
GCDN1:	ADD	#40,R1		; CONVERT CASE IF NECESSARY
	BR	GCINR		;
;	LOWER CASE LETTERS
GCUP:	TSTB	CASE		; CONVERSION NECESSARY
	BLE	GCINR		; NO
GCUP1:	SUB	#40,R1		; CONVERT TO UPPER CASE
	BR	GCINR		;
;	CAPITALIZE FLAG
GCCAP:	TSTNEB	$CFLSW+1,GCINR	; Flag temporarily disabled ?
	MOVB	#1,CASE		; SET WORD CAPITALIZE CONVERSION VALUE
	BR	GCIN		;
;	UNDERLINE FLAG
GCUNL:	TSTNEB	$UFLSW+1,GCINR	; Flag temporarily disabled ?
	BITNEB	#^C<SW.TDS>,$UNLSW,GCIN	; Permanently disabled ?
	TSTNE	@EQSTK,GCIN	; Equation in progress ?
	MOV	#ULCHS,R1	; SET TO UNDERLINE CHARACTER
	MOVB	R1,$UNLLN	; Set to mark this line as underlined
	JMP	GCINO		;
;	OVERSTRIKE FLAG
GCOVR:	TSTNEB	$OFLSW+1,GCINR	; Flag temporarily disabled ?
	BISB	#SW.TDS,$AUHYP	; Temporary disable hyphenation
	TSTNEB	$OVRSW,GCIN	; Overstrike disabled ?
	MOV	#BS,R1		; MAKE IT BACK SPACE
	ADD	PHSP,LINBK	; Add to remaining chars
	SUB	PHSP,SPCH	; Subtract from spacing characters
	BR	GCINO		;
;	HYPHENATE FLAG
GCHYP:	TSTNEB	$HFLSW+1,GCINR	; Flag temporarily disabled ?
	TSTNEB	RETSW,GCLF	; Return ?
	TSTNE	@EQSTK,50$	; Equation being formatted ?
	BISB	#SW.TDS,$AUHYP	; Set temporary no auto hyphenation
	TST	LINBK		; Check room on page
	BLE	GCIN		; No room for hyphenation ?
	CMPEQB	LCH,#SPC,GCIN	; Last char space ?
	CMPEQB	LCH,#TAB,GCIN	; or tab ?
	CMPEQB	LCH,#NXS,GCIN	; or non expandable space ?
	CALL	BRKSV
	MOV	SPCH,HYPSP	; Hyphenation spacing chars.
50$:	JMP	CONTIN
;	QUOTED SPACE FLAG
GCQTS:	TSTNEB	$QFLSW+1,GCINR	; Flag temporarily disabled ?
	TSTNEB	RETSW,GCLF	; Return ?
	MOVB	ULOCK,CASE	; RESET CASE
GCQTS1:	MOV	#NXS,R1		; SET NON EXPANDABLE SPACE
	BISB	#SW.TDS,$AUHYP	; Set temporary no auto hyphenation
	BR	GCINR1		; AND SAVE IT
GCINR::	BIC	#1002,CASE	; Reset temporary upper case conversion
GCINR1:	CALL	PUBYT0		; OUTPUT CHAR
	MOV	TESMSK,R4	; Cancel escapes ?
	BEQ	20$		; No ?
	CALL	ESCEND		; Cancel them
20$:	MOVB	LCH,R1
	BITEQB	#CH.BRK,CHTABL(R1),GCINR2	; No AutoBreak ?
	CMPEQB	R1,#SPC,GCINR2	; Space ?
	TSTNEB	$AUBRK,GCINR2	; No break ?
	TSTNE	@EQSTK,GCINR2	; Equation being formatted ?
	TST	LINBK		; Past end of line ?
	BLE	GCINR2		; Yes ?
	BISB	#SW.TDS,$AUHYP	; set temporary no hyphenation
	TSTEQB	$TABPD,30$	; No right tabs ?
	CALL	BRKTS		; Set them up
	BR	GCINR2		; done
30$:	CALL	BRKSV		; Set up break here
GCINR2:	SUB	PHSP,LINBK	; Subtract from char count remaining
	BEQ	20$
	BCC	70$		; NO
	CMPEQ	PHSP,#1,70$	; Single decrement ?
20$:	MOV	SPCH,LNINS	; Char count at last character
	TSTNE	BRCNT,30$	; NO breaks this line?
	CALL	BRKSV		; Save break here
30$:	TSTNEB	$GCEND,GCLF	; Immediate end requested?
70$:	JMP	GCIN		; Continue
GCLF:	RETURN
GCINO:	CALL	PBYT		; OUTPUT CHAR
	JMP	GCIN		; CONTINUE PARSING INPUT
;	ACCEPT FLAG
GCACC:	TSTNEB	$AFLSW+1,GCINR	; Flag temporarily disabled ?
	CALL	CCIN		; READ CHARACTER NO TRANSLATION
	CMPEQB	R1,#SPC,GCQTS1	; Space ? Make it quoted space
	BGT	1$		; Printable ?
	JMP	GCIN1		; Less than space ?
1$:	BIC	#1002,CASE	; Reset temporary upper case conversion
	CALL	PUBYT0		; OUTPUT CHAR
	BIS	#200,LCH	; Set for quoted char
	MOV	TESMSK,R4	; Cancel escapes ?
	BEQ	20$		; No ?
	CALL	ESCEND		; Cancel them
20$:	BR	GCINR2
;
;	ROUTINE TO READ INPUT FROM FILE AND REMOVE BAD INPUT
;		R1=	CHARACTER READ
;		R2-R5	are saved
;
CCIN::	MOV	BUFAD,R1	; input buffer header
	CALL	GBYT1		; get input
	BLOS	20$		; At end of buffer ?
	BIC	#^C<177>,R1	; CLEAR EXCESS BITS
	TSTB	GCTABL(R1)	; LEGAL CHARACTER?
	BLT	CCIN		; NO GET ANOTHER
	RETURN
20$:	TSTEQB	SUBSTK,30$	; End of input line ?
	CALL	POPINS		; Go down one entry
	BR	CCIN		; try again
30$:	CALL	FIN		; NO. READ FROM FILE
	BCC	CCIN		; Successful input ?
	RETURN			; None to get
;
;	routine to parse substitution - SUBSTITUTE FLAG
;
GCSUB:	TSTEQB	$SBFSW+1,1$	; Flag not disabled ?
	JMP	GCINR
1$:	MOV	R3,-(SP)	; save
	MOV	BUFAD,R3	; get buffer header for input
	MOV	#TBUFF-1,R2	; temporary buffer
	MOVB	R1,(R2)+	; Save flag
	CLRB	(R2)		; Clear in case no more
	MOV	BF.FUL(R3),-(SP) ; save current location
	MOV	#SUBMAX,R4	; max number of char/label
50$:	CALL	GBYT		; get input
	CMP	R1,#SPC		; non printable?
	BLE	60$		; yes, done
	CMPNEB	GCTABL(R1),#GC.LC,55$	; Not lower case ?
	CMPEQ	R2,#TBUFF,55$		; Not first char ?
	SUB	#40,R1		; Make it lower case
55$:	MOVB	R1,(R2)+	; Save char
	SOB	R4,50$		; no, continue
60$:	CLRB	(R2)+		; Chock end of string
	MOV	#TBUFF,R2	; Start of buffer
	CMPNEB	(R2),$SBFSW,65$	; First char not substitute flag ?
	MOVB	#'$,(R2)	; Make first char $
65$:	MOV	(SP)+,R1	; current location
	CALL	FNDBF		; go back to it
	CALL	FNDSB		; Find substitution
	MOV	(SP)+,R3	; restore
	JMP	GCIN
;
;	Find substitutions All registers destroyed
;
FNDSB::	CMPB	SUBSTK,SUBSTK+1	; max stack reached?
	BLO	40$		; no
	MOV	#ILSBST,R0	; Too many nestings error
	BR	20$
10$:	CALL	POPINS		; Back in stack
	MOV	#ILSBCM,R0	; Undefined command
	TSTB	TBUFF
	BLT	20$		; command ?
	.ifdf	$PASS		; 2 pass ?
	BITNEB	#SW.DIS,$OUTSW,110$ ; First of 2 passes ?
	.endc
	MOV	#ILSBND,R0	; Undefined substitution error
20$:	CALL	EROUT
	MOV	#TBUFF-1,R0	; Print substitution
	BICB	#200,1(R0)	; Clear extra bits
	CALL	ONLIN		; Output traceback
30$:	SEC
	return
40$:	CALL	PSHINS		; Set up input stack
	CALL	BEGBF		; Start at beginning
	CALL	GWRD		; First index
	BCS	10$		; None?
50$:	TSTEQ	R1,10$		; None ?
	CALL	FNDBF		; Find next entry
	CALL	GWRD		; get next index
	BCS	10$		; end, no escape found
	MOV	R1,R4		; save
	MOV	#TBUFF,R2	; temporary buffer
	MOV	BF.FUL(R3),BF.SPC(R3)	; Save index for traceback
60$:	CALL	GBYT		; Get next char in key word table
	BCS	10$		; None?
	BITEQ	R1,#140,90$	; End of search ?
70$:	CMPEQB	R1,(R2)+,60$	; match?
	TSTB	TBUFF		; Check first byte
	BGT	80$		; Not command ?
	DEC	R2		; Go back to last char checked
	CMPEQB	R1,#SPC,60$	; Space in table ?
	CMPNEB	-1(R2),#SPC,80$	; Char before last not space ?
	CMPEQB	(R2)+,#SPC,70$	; Current space ?
80$:	MOV	R4,R1		; Next entry index
	BR	50$		; search again
90$:	TSTB	TBUFF		; Check for command
	BGT	92$		; Not commad
	MOVB	(R2),R0		; Get terminal char
	CMPEQB	GCTABL(R0),#GC.UC,80$	; Upper case char ?
92$:	BITEQB	R1,#7,95$	; Not a number ?
	MOV	R1,R5
	CLR	-(SP)		; Chock stack
93$:	CALL	GWRD		; get the number
	TSTEQ	R1,94$		; Zero ?
	MOV	R1,-(SP)	; Save number
94$:	SOB	R5,93$
	MOVB	#'-,$SEPR	; Page separator
	CALL	ENDBF		; Set to end of buffer
	MOV	BF.FUL(r3),R4	; Save index
	MOV	BF.SPC(R3),BF.VSP(R3); Save traceback
	CALL	PAGCV		; And convert number
	MOV	BF.VSP(R3),BF.SPC(R3); Restore
	CALL	CBYT		; Chock it
	MOV	R4,R1		; Beginning of string
	CALL	FNDBF		; Set to scratch location
95$:	MOV	R2,R1		; end of string
	SUB	#TBUFF,R1	; find string length
	MOVB	SUBSTK,R3	; Get subst stack
	MOV	BUFADD-2(R3),R3	; Old stack
	ADD	BF.FUL(r3),R1	; Add offset to start of string
	CALL	FNDBF		; And new location
	TSTB	TBUFF
	BLT	110$		; Command ?
	TSTEQB	$SUBSW,110$	; substitution not suppressed?
100$:	JMP	POPINS		; Reset subst
110$:	CLC
	RETURN			; done, continue with normal sequence
;
;	TAB character handled here.  It is expanded.
;
GCTAB:	TSTNEB	$TBFSW+1,1$	; Flag disabled ?
	TSTNE	@EQSTK,1$	; Equation being formatted ?
	TSTNEB	$CENSW,1$	; Centering enabled ?
	TSTNEB	$RIGSW,1$	; Right justify enabled
	TSTEQB	$TABSW,2$	; Tabs allowed ?
1$:	JMP	GCSPC		; NO!
2$:	BISB	#SW.TDS,$AUHYP	; No autohyphenation now
	MOVB	ULOCK,CASE	; RESTORE CASE
	CALL	BRKTS		; Test + execute right tabs
	CLR	R2
	CALL	TABB		; FIND WHERE NEXT TAB STOP IS
	CMP	R2,LINBK	; Does this exceed line size?
	BLE	20$		; It is OK ?
	TST	LINBK		; Currently too long ?
	BLT	10$		; Yes
	CALL	BKSPI		; Backup over tab to save it
	CALL	BRKSV		; No, put break here
10$:	MOVB	#TAB,R1		; Current char
	RETURN
20$:	MOV	#TABBF,R1	; Get status
	CALL	GBYT1		;
	BITNE	#TB.L,R1,30$	; Tab only left
	BITNE	#TB.R!TB.C,R1,25$; Tab only right
	TSTEQB	$TABLF,30$	; Left justify  tabs ?
25$:	MOV	#1,R2		; Only 1 space for right justify
	MOVB	R2,$TABPD	; Now set 1 tab pending
	BISB	R1,$TABPD	; Set for right tab
30$:	CMPNEB	LCH,#TAB,35$	; Was last char not tab ?
	TSTEQ	LTAB,35$	; No tab pending
	SUB	R2,LINBK	; AND DECREMENT LINBK COUNT BY THAT AMOUNT
	ADD	R2,SPCH		; Add to spacing characters
	CALL	ADDTAB		; Add r2 to previous tab
	BR	TABXIT		;
35$:	SUB	R2,LINBK	; Subtrac from remaining space
	ADD	R2,SPCH		; Add to spacing characters
	TSTEQB	BRCNT,36$	; Beginning of line ?
	CALL	BKSPI		; Backup over tab to save it
	CALL	BRKSV		; Save break before tab
	CALL	CCIN
	BR	37$
36$:	CALL	BRKSV		; Set break after tab
37$:	MOVB	#TAB,LCH	; LAST CHAR
	MOVB	#TABO,R1	; Set to output tab
	MOVB	@TABBF+BF.ADD,R4; Ellipses count
	BIC	#^C<TB.CNT>,R4	; Clear count
	BNE	39$		; Ellipses spec ?
	TSTEQB	$ELIPS,40$	; No ellipses?
39$:	MOVB	#ELIP,R1	; Yes, set to output ellipses
40$:	CALL	PBYT		; Into buffer
	MOV	R2,R1		; Number of spaces
	CALL	PBYT		; Into buffer
	MOV	BF.ADD(R3),LTAB	; Address of last tab char
	TSTNEB	$ELIPS,45$	; Ellipses ?
	TSTEQ	R4,TABXIT	; No ellipses ?
45$:	MOV	R4,R1		; Ellipses count
	CALL	PBYT
	TSTEQ	R4,TABXIT	; Done ?
50$:	MOV	#TABBF,R1
	CALL	GBYT1		; Put ellipses into buffer
	CALL	PBYT
	SOB	R4,50$
TABXIT:	JMP	GCIN		; Next char
;
;	End of line action, space if fill disabled
;
GCCR:	CALL	BRKTS		; Test tab + break
	TSTNEB	$CENSW,10$	; Centering enabled ?
	TSTNEB	$RIGSW,10$	; Right justify enabled
	BITNE	#FILLF,F.1,GCSPC ; Fill enabled ?
10$:	TST	LINBK		; Past end of line ?
	BGE	TABXIT		; No ?
	RETURN			; Yes !
;
;	Handle spaces in input stream
;
GCSPC::	TSTNEB	RETSW,SPCRET	; Return ?
	MOVB	ULOCK,CASE	; RESTORE CASE
	TSTNE	@EQSTK,25$	; Equation being formatted ?
	TST	LINBK		; Line full ?
	BGE	10$		; NO ?
	RETURN			; Yes, break for full line
10$:	BITEQB	#CH.BRK,CHTABL+SPC,15$	; No AutoBreak ?
	CALL	BRKTS		; Test and set up right tabs
15$:	BITEQ	#FILLF,F.1,30$	; FILL disabled ?
	MOVB	LCH,R1		; GET PREVIOUS CHARACTER WHAT WAS IT?
	BEQ	TABXIT		; Start of new line ?
	BLT	30$
	CMPEQB	R1,#SPC,TABXIT	; Space before space ?
	CMPEQB	R1,#TAB,TABXIT	; Tab before space ?
	CMPEQB	R1,#NXS,TABXIT	; Non expandable space before space ?
	CMPEQB	R1,#CPER,17$	; Is it following period char?
	TSTEQB	$PERSW,30$	; Automatic punctuation spacing disabled ?
	BITEQB	#CH.PER,CHTABL(R1),30$ ; Not Punctuation before space ?
17$:	CMP	LINBK,#1	; Space left ?
	BLE	30$		; No
20$:	CALL	50$		; Set up for space
	CALL	PUBYT0		; Save space
	SUB	PHSP,LINBK	; And subtract from char left
25$:	MOV	#NXS,R1		; Next output non expandable space
	BR	40$		;
30$:	CALL	50$		;
40$:	BICB	#SW.TDS,$HYPSW	; Allow hyphenation
	BICB	#SW.TDS,$AUHYP	; Allow auto hyphenation
	CLR	HYPSP
45$:	JMP	GCINR1		; RETURN CHAR.
;
;	Section to insert spaces
;
50$:	BITEQB	#CH.BRK,CHTABL+SPC,55$	; No AutoBreak ?
	CALL	BRKSV		; Set up for break here
55$:	TSTNEB	$NOSPC,70$	; No expandable spaces allowed ?
	INC	SPCNT		; COUNT THIS SPACE
	MOV	#SPC,R1		; SPACE CHARACTER (EXPANDABLE)
60$:	RETURN			;
70$:	MOV	#NXS,R1		; Make it non expandable
SPCRET:	RETURN
GCPER:	TSTNEB	$PFLSW+1,10$	; Period flag disabled ?
	MOVB	#CPER,LCH	; Last is period flag
	JMP	GCIN
10$:	JMP	GCINR		; Output char
;
;	break flag here
;
GCBRK:	TSTEQB	$BRFSW+1,1$	; Flag not disabled ?
	JMP	GCINR
1$:	TSTNEB	RETSW,SPCRET	; Return ?
	TSTNE	@EQSTK,CONTIN	; Equation being formatted ?
	BISB	#SW.TDS,$AUHYP	; set temporary no hyphenation
	TST	LINBK		; Past end of line
	BGE	10$		; Not yet
	RETURN
10$:	TSTEQB	$TABPD,20$	; No right tabs ?
	CALL	BRKTS		; Set them up
	BR	CONTIN		; done
20$:	CALL	BRKSV		; Set up break here
CONTIN:	TSTNEB	$CONT,20$	; Continue disabled ?
	CALL	CCIN		; Get next char
	CMPNEB	R1,#CR,40$	; Not CR
	CALL	FIN		; Next line
	CALL	LSINSV		; Save input line
20$:	JMP	GCIN		; And next line
40$:	JMP	GCIN1		; next char
;
;	Test and set up right tab
;
	.ENABL	LSB
BRKTS:	MOVB	$TABPD,R0	; Check pending tabs
	BEQ	10$		; No tab pending?
	CLRB	$TABPD		; No more tabs pending
	TSTEQ	LTAB,10$	; No tab address ?
	MOV	#-1,R2		; Initial tab
	BITEQ	#TB.C,R0,5$	; No centered tabs ?
	MOV	SPCH,R0		; Get text size
	SUB	LSPCH,R0	; Minus previous size
	DEC	R0		; Account for tab
	ASR	R0		; Divided by 2
	SUB	R0,R2		; Subtract from Offset
5$:	CALL	TABB		; Find next tab stop
	DEC	R2		;
	CMP	R2,LINBK	; Too many for line ?
	BGT	10$		; YES. TREAT AS SPACE, NOT TAB
	ADD	R2,SPCH		; Spacing chars
	SUB	R2,LINBK	; Current length this line
ADDTAB:	MOVB	@LTAB,R1	; Get last tab
	ADD	R2,R1		; Add on more
	MOVB	R1,@LTAB	; Increment old tab
10$:	RETURN
	.DSABL	LSB
;
;	Set up break (save current character status)
;
BRKSV::	CLR	HYPSP
	CALL	LSINSV		; save input addresses
	INC	BRCNT		; count breaks this line
	MOV	PHSP,LPHSP	; Spacing at break
	MOV	CASE,CASSAV	; SAVE CURRENT CASE
	MOV	BF.FUL(R3),LSTSP ; POSITION IN BUFFER
	MOV	ESMSK,LESMSK	; Save current escape mask
	MOVB	$UNLSW,LUNLSW	; And underline status
	MOVB	LCH,LSCH	; SAVE CHAR BEFORE SPACE
	MOV	SPCNT,SPCNSV	; Save old space count
	MOV	SPCH,LSPCH	; Save current spacing char count
	RETURN

;
;	Here we handle Index flag
;
GCIFL:	TSTEQB	$IFLSW+1,10$	; Autoindex flag on ?
	JMP	GCINR		; No, ouput char
10$:	CALL	AINDEX		; Do autoindex
	JMP	GCIN		; Continue
;
;	SUBINDEX FLAG
;
GCSIX:	TSTEQB	$SIFSW+1,10$	; Autoindex flag on ?
	JMP	GCINR		; No, ouput char
10$:	CMPNEB	LCH,#SPC,20$	; Not last space
	MOV	LSTSP,R1	; Abort last space
	CALL	RSTBF		; Terminate buffer here
20$:	CLR	LCH		; Set last to null
	MOVB	#SXCHR,R1	; Get subindex character
	JMP	GCINO		; Save subindex flag
;
;	HERE WE HANDLE SEPARATE ESCAPE SEQUENCES
;
GCESC:	TSTEQB	$EFLSW+1,1$	; Flag not disabled ?
	JMP	GCINR
1$:	MOV	R1,R5		; First character
	CALL	CCIN		; GET NEXT CHAR
GCES1:	CALL	ESCSEQ		; ESCAPE SEQUENCE?
	BCC	10$		; No ?
	MOV	#ILUNES,R0	; Message undefined escape
	CALL	ILCMC		; Output error message
10$:	JMP	GCIN		; NEXT CHAR
;
;	Special Flag character detected
;
GCSPF:	TSTEQB	$SPFSW+1,1$	; Flag not disabled ?
	JMP	GCINR
1$:	MOV	#'^+100000,R5	; Move in shift up operator+ temp flag
	CALL	ESCSEQ		; Execute sequence
	BCC	10$		; Not executed ?
	MOV	#ILUNES,R0	; Message undefined escape
	CALL	ILCMC		; Output error message
10$:	JMP	GCIN		; Continue
;
;	SUBROUTINE TO FIND ESCAPE SEQUENCE FROM TABLE
;
;		R4=Escape sequence mask
;		R3	is preserved/ all other registers changed
	.enabl	LSB
ESCBEG:: CLR	R5		; Look for begin sequence
	BR	1$
ESCEND:: MOV	#177,R5		; Look for end sequence
1$:	TSTEQ	R4,7$		; No escapes ?
	TSTNEB	$ESCSW,7$	; Escapes disabled ?
	MOV	R3,-(SP)	; Save current buffer
	MOV	#ESCBF,R3	; Escape buffer
	CALL	BEGBF		; Start at beginning
	MOV	(SP)+,R3	; Restore
2$:	TSTEQ	R4,7$		; Done ?
	CALL	11$		; Do next sequence
	BCC	2$		; Ok ?
7$:	RETURN
11$:	MOV	R3,-(SP)	; Save current buffer
	MOV	#ESCBF,R3	; Escape buffer
12$:	CALL	GBYT		; Get count
	BCS	17$		; Done ?
	MOV	BF.FUL(R3),-(SP)	; And current index
	MOV	R1,R2		; Character count
	CALL	GBYT		; Skip 1 byte
	CALL	GBYT		; Skip 1 byte
	CALL	GBYT		; Skip 1 byte
	MOV	R1,-(SP)	; Save status
	BITNEB	#ES.LCK,R1,4$	; Is this lock status ?
3$:	TST	(SP)+		; Pop status
	MOV	R2,R1		; number of bytes to skip
	ADD	(SP)+,R1	; New index
	CALL	FNDBF		; skip them
	BR	12$		; Try again
4$:	CALL	GBYT		; Get lock byte
	BLT	5$		; Unlock ?
	TSTNEB	R5,3$		; Lock desired ?
	ADD	#BITABL,R1	; Now points to table
	BITEQ	(R1),R4,3$	; Not requested escape ?
	BIC	(R1),R4		; Clear 1 bit
	BR	31$		; Ok!
5$:	TSTEQB	R5,3$		; Unlock desired ?
	ADD	#BITABL-177600,R1	; Compensate for hi bits
	BITEQ	(R1),R4,3$	; Not requested escape ?
	BIC	(R1),R4		; Clear 1 bit
	BITNE	(R1),TESMSK,32$	; Clearing temporary bit?
	BR	31$
;
;	R5	= first char
;	R1	= second char
;	R3,R5	are preserved
;	C	= set if sequence not found
;
ESCSEQ:	MOV	R3,-(SP)	; save current buffer
	MOV	#ESCBF,R3	; escape buffer
	MOV	R1,R4		; SAVE CHAR
	CALL	BEGBF		; Start at beginning
10$:	CALL	GBYT		; get beginning of sequence
	BCC	20$		; not end of table?
	MOVB	R4,R1		; GET CHAR BACK
17$:	MOV	(SP)+,R3	; restore
15$:	SEC			; NO SEQ FOUND
	RETURN
20$:	MOV	BF.FUL(R3),-(SP)	; And save current index
	MOV	R1,R2		; number of bytes in sequence
	CALL	GBYT		; get next bytes
	CMPNEB	R5,R1,25$	; MATCH WITH CHAR?
	CALL	GBYT		; get next bytes
	CMPEQB	R4,R1,30$	; MATCH WITH CHAR?
25$:	MOV	R2,R1		; number of bytes to skip
	ADD	(SP)+,R1	; add on current index
	CALL	FNDBF		; skip them
	BR	10$
30$:	TSTEQB	$ESCSW,27$	; ESCAPE SEQUENCES not DISABLED?
	JMP	55$		; Disabled
27$:	BISB	#SW.TDS,$AUHYP	; set temporary no hyphenation
	CALL	GBYT		; Get flag byte
	BEQ	40$		; No flag byte ?
	MOVB	R1,-(SP)	; Save bit mask
	BITEQB	#ES.LCK,(SP),31$	; Not lock/Unlock ?
	CALL	GBYT			; Get lock word
	BLT	21$			; Unlock ?
	ADD	#BITABL,R1		; Points to bit table
	BITNE	(R1),ESMSK,54$		; Is it currently locked on ?
	BIS	(R1),ESMSK		; Lock it on
	TST	R5			; Do we do temporary lock
	BGT	31$			; No
	BITEQB	#ES.CHR,(SP),31$	; Not temporary sequence
	BIS	(R1),TESMSK		; Set temporary mask
	BR	31$
21$:	ADD	#BITABL-177600,R1	; Compensate for hi bits
	BITEQ	(R1),ESMSK,54$		; Currently locked off ?
32$:	BIC	(R1),ESMSK		; Lock it off
	BIC	(R1),TESMSK		; Clear temporary mask also
31$:	BITEQB	#ES.VSP,(SP),33$	; No vertical spacing
	CALL	GBYT			; Get vertical spacing
	TSTNEB	$PAGNG,299$		; No paging ?
	SUB	R1,LINEC3		; Decrement lines left
	ADD	R1,BF.VSP(R3)		; Add to saved spacing
299$:	ADD	CURVS,R1		; Add on current VS
	MOV	R1,CURVS		; Save current
	CMP	R1,MINVS		; Compare with min
	BGT	311$			; Bigger ?
	MOV	R1,MINVS		; New min
311$:	CMP	R1,MAXVS		; Compare with max
	BLT	312$			; Smaller ?
	MOV	R1,MAXVS		; New max
312$:	ADD	R1,BF.VSP(R3)		; Count deferred text line
33$:	BITEQB	#ES.HSP,(SP),37$	; No Horizontal spacing
	CALL	GBYT			; Get horizontal spacing
	BITNEB	#ES.PSP,(SP),35$	; Permanent spacing ?
	MOVB	R4,LCH		; Set last char
	ADD	R1,SPCH		; Count spacing chars
	SUB	R1,LINBK	; And remove from available spaces
	BR	37$
35$:	BICB	#40,$NOSPC	; Set for expandable spaces ok
	BICB	#40,$TABSW	; Enable tabs
	MOV	R1,PHSP		; Set permanent horiz spacing
	BICB	#SW.TD2,$AUHYP	; Temporary hyphenation off
	CMPEQ	R1,#1,37$	; Spacing 1 ?
	BISB	#SW.TD2,$AUHYP	; set temporary no hyphenation
	BISB	#40,$NOSPC	; Set no expandable spaces
	BISB	#40,$TABSW	; Set no tabs
37$:	TST	(SP)+		; Pop saved flags
40$:	MOV	(SP)+,R1	; Index for transfer
	ADD	#2,R1		; Points to status now
	SUB	#2,R2		; Number of bytest to transfer
	CALL	FNDBF		; Go back to start of sequence
	MOV	(SP)+,R3	; Output buffer
	MOV	#ESC,R1		; Mark escape sequence in output buffer
45$:	CALL	PUBYT		; OUTPUT IT
50$:	MOV	#ESCBF,R1	; escape buffer
	CALL	GBYT1		; get next bytes
	CALL	PBYT		; OUTPUT CHAR
	SOB	R2,50$
	CALL	CBYT		; Null Into buffer
	BR	60$
54$:	TST	(SP)+		; Pop stack
55$:	TST	(SP)+		; Pop stack
	MOV	(SP)+,R3	; Restore buffer address
60$:	CLC			; SUCCESS
	RETURN			;
	.DSABL	LSB
;
;	ROUTINE TO FIND NEXT TABSTOP FOR OUTLIN ROUTINE.
;	INPUT	R2=	Space to include
;	OUTPUT	R2=	DISTANCE TO NEXT STOP
;		R0,R1 are destroyed
;
TABB:	MOV	R3,-(SP)	; Save R3
	MOV	#TABBF,R3	; Set to search tab buffer
	CALL	BEGBF		; Start at beginning
	ADD	SPCH,R2		; NUMBER OF SPACING CHARS
	ADD	LMARG,R2	; ADD ON LEFT MARGIN
	ADD	INDCT,R2	; PLUS INDENTATION
10$:	CALL	GWRD		; Get next tab
	BCS	30$		; End of buffer ?
	CMP	R1,R2		; Compare tab with current position
	BGT	20$		; Larger than current ?
	CALL	GBYT		; Get status
	BIC	#^C<TB.CNT>,R1	; Chars to skip
	BEQ	10$		; None
	ADD	BF.FUL(R3),R1	; Add on current location
	CALL	FNDBF		; Skip em
	BR	10$
20$:	CMP	R1,RMARG	; Compare with right margin
	BLE	40$		; Is it smaller than margin ?
30$:	MOV	RMARG,R1	; No ASSUME A TABSTOP AT RIGHT END
40$:	SUB	R2,R1		; GET DISTANCE TO TABSTOP
	MOV	R1,R2		; ANSWER IN A
	BGT	50$		; At least 1 space?
	MOV	#1,R2		; No make it 1
50$:	MOV	(SP)+,R3	; Restore
	RETURN			;

;
;	UPPER CASE FLAG
;
	.ENABL	LSB
SHFUP:	TSTEQB	$SFLSW+1,1$	; Flag not disabled ?
	JMP	GCINR
1$:	CALL	CCIN		; READ A CHARACTER
	BITEQB	CHTABL(R1),#CH.FLG,40$	; Not flag character ?
	CMPNE	R1,$UFLSW,10$	; LOCK ON UNDERLINE?
	BICB	#SW.TDS,$UNLSW	; UNDERLINING POSSIBLY ON
	BR	30$
10$:	CMPNE	R1,$CFLSW,20$	; NOT LOCK UPPER CASE?
	MOV	#401,CASE	; SET UPPER CASE + LOCK
	BR	30$		; READ ONOTHER CHAR
20$:	CMPNE	R1,$SFLSW,40$	; NOT UNLOCK ALL?
	CALL	UPCAS		; SET TO UPPER CASE
30$:	JMP	GCIN		; AND GO READ ANOTHER CHARACTER
40$:	MOVB	$SFLSW,R5	; MATCH CHAR
	CALL	ESCSEQ		; SEARCH FOR ESCAPE SEQUENCE
	BCC	30$		; FOUND ONE!
	MOVB	GCTABL(R1),R0	; CHAR TYPE?
	CMPNE	R0,#GC.LC,50$	; NOT LOWER CASE?
	JMP	GCUP1		; LOWER CASE, SHIFT IT.
50$:	CMP	R0,#GC.LC	; ALPHABETIC CHAR?
	BLE	60$		; YES, DO NOT EXECUTE IT
	JMP	@GCJMP(R0)	; DISPATCH IT
60$:	JMP	GCINR
;
;	LOWER CASE FLAG DETECTED
;
SHFDN:	TSTEQB	$LFLSW+1,2$	; Flag not disabled ?
	JMP	GCINR
2$:	CALL	CCIN		; GET ANOTHER CHARACTER
	BITEQB	CHTABL(R1),#CH.FLG,80$	; Not flag character ?
	CMPNE	R1,$UFLSW,70$	; UNLOCK UNDERLINE?
	BISB	#SW.TDS,$UNLSW	; UNDERLINING OFF
	BR	30$		;
70$:	CMPNE	R1,$LFLSW,80$	; NOT LOWERCASE LOCK?
	CALL	LWCAS		; SET LOWER CASE SHIFT
	BR	30$		;
80$:	MOVB	$LFLSW,R5	; MATCH CHAR
	CALL	ESCSEQ		; HANDLE ESCAPE SEQUENCES
	BCC	30$		; FOUND ESC SEQ
	MOVB	GCTABL(R1),R0	; CHAR TYPE?
	CMPNE	R0,#GC.UC,50$	; NOT UPPER CASE?
	BITNE	#UPCSW,$SWTCH,60$ ; IS UP SHIFT MANDATED?
	JMP	GCDN1		; SHIFT TO LOWER CASE
	.DSABL	LSB

;
; CASE SELECTION COMMANDS
;

	.ENABL	LSB
LWCAS::	MOV	#-1,R1		; SET FOR CONVERSION TO LOWER CASE
	BR	10$		;
UPCAS::	CLR	R1		; SET FOR NO CASE CONVERSION
10$:	BITEQ	#UPCSW,$SWTCH,20$	; Not Upper case only?
	MOV	#401,R1		; FORCE TO UPPER CASE
20$:	MOV	R1,CASE		; SET CASE CONVERSION
	RETURN			;
	.DSABL	LSB
;
; COROUTINE TO SHIFT TO UPPER CASE TEMPORARILY
;

SHFUC::	MOV	(SP),-(SP)	; COPY RETURN ADDRESS
	MOV	CASE,2(SP)	; SAVE CURRENT CASE
	MOV	#401,CASE	; UPPER CASE ONLY
	CALL	@(SP)+		; CALL THE CALLER BACK
	MOV	(SP)+,CASE	; RESTORE PREVIOUS CASE
SHXIT:	RETURN			;
;
;	PUT STRING ENDED BY ZERO BYTE TO BUFFER
;		R0=	STRING ADDRESS
;
PSTRZB::MOV	R2,-(SP)	; Save R2
	MOV	R0,R2
10$:	MOVB	(R2)+,R1	; Get char
	BEQ	20$		; If zero done ?
	CALL	PBYT		; PUT IT
	INC	BF.SPC(R3)	; Count chars
	BR	10$		; CONTINUE
20$:	MOV	(SP)+,R2	; Restore
	RETURN

;
; ROUTINES TO OUTPUT A STRING TO THE OUTPUT FILE
;	R3=BUFFER ADDRESS FOR STRING
;		Output terminates at either null or end of input buffer
;		Z or C tell user what form of termination occurred.
;
;		This one starts at top of buffer
PSTRPA::CALL	BEGBF		; SET TO TOP OF BUFFER
	CLRB	EXSP1		; No multiple spaces
	CLRB	EXSP2		; No multiple spaces
	CLRB	EXSP3		; No multiple spaces
	CLRB	EXSTAT		; No status
	MOVB	#-1,EXMSP	; No multiple micro spaces
;
;	This one starts anywhere in buffer
;		R3 is preserved all other registers destroyed
;
CCOUT::	CLRB	$ULOSW		; No underlining at first
CCOUT1:	CLRB	$ULOSW		; Reset underlining
CCOUT2:	CALL	GBYT		; Get 1 byte
	BCS	GOEND
	BGT	10$		; No extra bits
	BEQ	GOEND		; End of input buffer ?
	INCB	$ULOSW		; Set underline
	BIC	#^C<177>,R1	; Clear extra bits
10$:
	CMPEQB	R1,#SPC,GOSPC	; Is it space ?
	MOVB	GCTABL(R1),R0	; GET CHAR TYPE
	BGE	GOPRN		; PRINTABLE
	JMP	@GCJMP(R0)	; EXECUTE FUNCTION
;	Handle single underline
GOUNL:	INCB	$ULOSW
	BR	CCOUT2
;	Printable char
GOPRN:	CALL	CCPRN		; Print 1 char
	BR	CCOUT1
GOSPC:	MOVB	EXSP1,-(SP)	; YES. HOW MANY MULTIPLE SPACES?
	MOVB	EXMSP,1(SP)	; Micro spaces
	DECB	EXSP2		; TO EXTRA BLANKS YET?
	BGE	70$		; NO.
	TSTEQB	EXSP3,80$	; EXTRA SPACES TO RIGHT?
	BR	90$		; LEFT. NO MORE EXTRAS, JUST LOOP
70$:	TSTEQB	EXSP3,90$	; NO EXTRA SPACES LEFT OR RIGHT?
80$:	BITEQB	#HD.VAR,EXSTAT,85$	; No micro spacing ?
	INCB	1(SP)		; Micro spacing count
	BR	90$
85$:	INCB	(SP)		; Extra space to output
90$:	BITEQB	#HD.VAR,EXSTAT,110$	; No micro spacing ?
	MOVB	1(SP),R1	; count
	BLE	110$		; micro count too small ?
	TSTEQB	$ULMSW,94$	; Underline by BS ?
	MOV	CPOS,R0		; Current position
	CMP	R0,#ULNSZ	; check with max
	BHI	95$		; Too big ?
	BIS	#200,R1		; Now is count for underline buffer
	MOVB	R1,UBUFF-1(R0)	; Into buffer
	MOVB	#-1,$UNLRS
	INC	CPOS		; Next position
	BR	95$
94$:	TSTEQB	$ULOSW,95$	; No underlining ?
	MOV	#1,R2		; Number of chars to underline
	CALL	CCUNL
95$:	DECB	1(SP)		; Count micro spaces
	BLT	110$		; None ?
	MOV	#VARESC+1,R2	; Address of escape sequence buffer
100$:	MOVB	(R2)+,R1	; Data to output
	BEQ	95$		; Another to output
	CALL	FOUT		; Output it
	BR	100$		; And try again
110$:	CALL	CCSPC		; OUTPUT SPACES
	DECB	(SP)		; Decrement counter
	BGT	110$		; Not done ?
	TST	(SP)+		; Pop counter
	JMP	CCOUT1
GOQTS:	CALL	CCSPC		; Turn quoted space to single space
	JMP	CCOUT1
GOEND:	RETURN
GOESC:	CALL	GBYT		; Get flag byte
	BEQ	90$		; No flag byte ?
	MOVB	R1,-(SP)	; Save bit mask
	BITEQB	#ES.LCK,(SP),10$	; Not lock/Unlock ?
	CALL	GBYT			; Get lock word
10$:	BITEQB	#ES.VSP,(SP),20$	; No vertical spacing
	CALL	GBYT			; Get vertical spacing
	TSTNEB	$PAGNG,20$		; No paging
	SUB	R1,LINEC1		; Decrement lines left
	SUB	R1,LINEC2		; Decrement lines left
20$:	BITEQB	#ES.HSP,(SP),80$	; No Horizontal spacing
	CALL	GBYT			; Get horizontal spacing
	BLE	80$			; Too small ?
	BITNEB	#ES.PSP,(SP),40$	; Permanent spacing ?
	TSTNEB	$ULOSW,30$		; Underline ?
	ADD	R1,CPOS			; No
	BR	80$
30$:	MOV	R1,R2			; Number of undelines
	CALL	CCUNL			; Perform underlining
	BR	80$
40$:	MOV	R1,PHSPOU		; Set permanent horiz spacing
;
;	Now output escape sequence
;
80$:	TST	(SP)+
90$:	CALL	GBYT		; Get escape sequence chars
	BEQ	100$		; Done ?
	CALL	FOUT		; Output char with no interpretation
	BR	90$		; More ?
100$:	JMP	CCOUT1		; End of escape seq buffer ?
;	Handle backspaces
GOBS:	SUB	PHSPOU,CPOS		; New position
	BGT	10$		; OK ?
	MOV	#1,CPOS		; No, make it 1
10$:	CALL	FOUT		; Output backspace
	JMP	CCOUT1
;	Handle tabs
GOTAB:	CALL	GBYT		; Get next input byte
	MOVB	R1,-(SP)	; Save it
10$:	DECB	(SP)		; Done?
	BGE	20$		; Not done yet
	TST	(SP)+		; Pop stack
	JMP	CCOUT1
20$:	CALL	CCSPC		; Output a space
	BR	10$		; Check it
;	Handle tabs with ellipses
GOELP:	CALL	GBYT		; Get 1 byte
	CLR	-(SP)		; Clear counter on stack
	MOVB	R1,(SP)		; Save count
	CALL	GBYT		; Get ellipses count
	MOV	#TBUFF,R4	; Temporary buffer
	MOV	R1,R2		; Count
	MOV	R1,R5		; Count
	BEQ	6$		; No ellipse spec ?
5$:	CALL	GBYT		; Get chars
	MOVB	R1,(R4)+	; Till done
	SOB	R5,5$		; Get them all
	BR	7$
6$:	MOVB	#' ,(R4)+	; set first
	MOVB	#'.,(R4)+	; second
	MOV	#2,R2		; And count
7$:	CLRB	(R4)+		; chock buffer
	DEC	(SP)		; Output 1 char ?
	BLE	15$		; No, done
	CALL	CCSPC		;
	DIV$	R2,CPOS		; Divide CPOS/R2 result = R0
	ADD	#TBUFF-1,R1	; Add on temporary buffer address
	MOV	R1,ADDR
10$:	DEC	(SP)
	BGT	20$		; Spaces to output ?
15$:	BLT	16$		; No output ?
	CALL	CCSPC		; Output 1 space
16$:	TST	(SP)+		; Done so pop stack
	JMP	CCOUT1
20$:	INC	ADDR
	MOVB	@ADDR,R1	; Char to print
	BNE	30$		; Char ok ?
	MOV	#TBUFF-1,ADDR	; No, start at beginning
	BR	20$
30$:	CALL	CCPRN		; Output printable char
	BR	10$
;
;	Handle repeated output
;
GOREP:	CALL	GBYT		; Get repeat count
	BEQ	50$		; Repeat zero ?
	CLR	-(SP)		; Clear count on stack
	MOVB	R1,(SP)		; Save count
	MOV	BF.FUL(R3),-(SP)	; Save input index
10$:	CALL	CCOUT1		; Now output string
	DEC	2(SP)		; Done ?
	BLE	20$		; Yes ?
	MOV	(SP),R1		; Rewind input buffer
	CALL	FNDBF		; Back over string
	BR	10$		; Repeat
20$:	ADD	#4,SP		; Pop stack
	JMP	CCOUT1		; And continue
50$:	CALL	55$		; Stack up reequest to kill repeat
	JMP	CCOUT1		; And continue
55$:	CALL	GBYT		; Get char
	BNE	60$		; Not done ?
	RETURN
60$:	CMPEQB	R1,#ESC,70$	; Escape sequence ?
	CMPNEB	R1,#REPO,55$	; No repeat ?
	CALL	GBYT		; Skip count
	CALL	55$		; Stack another skip
	BR	55$		; Done with imbedded repeat
70$:	CALL	GBYT		; Skip status
80$:	CALL	GBYT		; Get sequence
	BNE	80$		; Not terminator ?
	BR	55$
;
;	section to fill in index entries
;
GOINX:	CALL	GWRD		; Get address inside index buffer
	MOV	R1,R4		; backward link
	MOV	R3,-(SP)	; Save
	MOV	#INXBF,R3	; Get index buffer address
	CALL	FNDBF		; get next entry
	BCS	90$
	CALL	GWRD		; get link to next
	MOV	R1,R5
10$:	MOV	R5,R1		; next entry
	BEQ	15$		; End of line ?
	CALL	FNDBF		; find it
	BCS	90$		; OK ?
	CALL	GWRD		; get next foreward link
	BCS	90$		; end of input
	MOV	R1,R2
	CALL	GBYT		; get status byte
	BCS	90$		; end of input
	BITNE	#X.ENT,R1,15$	; No entry ?
	MOV	R5,R4		; R4 has backward link
	MOV	R2,R5		; next foreward link
	BR	10$
15$:	MOV	R4,R1		; Go back to last one
	CALL	FNDBF		; Get the index entry address
	BCS	90$
	MOV	BF.MAX(R3),R1	; New entry address
	CALL	PWRD		; Link to end
	CALL	ENDBF		; Now go to end
	MOV	R5,R1		; Save foreward link
	CALL	PWRD
	MOV	#X.PAG,R1	; Set for page number
	TSTNEB	$CHPSW,30$	; no chapter print?
	TSTEQB	APNDN,20$	; No appendix?
	BIS	#X.AP,R1	; Set appendix status
	BR	30$		; no chapter if appendix
20$:	TSTEQB	CHPTN,30$	; No chapter?
	BIS	#X.CH,R1
30$:	TSTEQB	SUBPGE,40$	; No subpage?
	BIS	#X.SPG,R1
40$:	CALL	PBYT		; Save status bits
	TSTNEB	$CHPSW,60$	; no chapter print?
	MOV	APNDN,R1
	BEQ	50$
	CALL	PBYT		; put appendix
	BR	60$
50$:	MOVB	CHPTN,R1
	BIC	#^C<377>,R1	; Clear extra
	BEQ	60$
	CALL	PBYT		; put chapter
60$:	MOV	PAGENO,R1
	BNE	65$		; Not zero ?
	INC	R1		; Make it 1
65$:	BIS	PAGDSP,R1	; Add on display bits
	CALL	PWRD		; put chapter
70$:	MOV	SUBPGE,R1
	BEQ	80$
	CALL	PBYT		; put subpage
80$:	MOV	(SP)+,R3	; Restore
	JMP	CCOUT1
90$:	CALL	HLTER
;
;	Routine to output TOC entries
;
GOTOC: MOV	#TTBUF,R2	; Get temporary buffer
10$:	CALL	GBYT		; Get 1 byte
	MOVB	R1,(R2)+	; Into buffer
	BNE	10$
	MOV	#TTBUF+1,R1	; Address of array
	SUB	R1,R2		; Size of array
	DEC	R2		; Final
	BLE	40$		; None ??
	CALL	OUTTOC		; Output the toc line
	TSTB	TTBUF		; Check type of output
	BLE	40$		; No number requested ??
	MOV	R3,-(SP)	; Save R3
	MOV	#TTBF,R3	; Get temporary buffer
	CALL	CLRBF		; Clear it
	MOV	#TAB,R1		; Tab char.
	CALL	PBYT		; into buffer
	CALL	PUTPAG		; Get page number
	MOV	BF.FUL(R3),R2	; Get size
	MOV	(SP)+,R3	; Restore
	MOV	#TTBUF,R1	; Start of buffer
	CALL	OUTTOC		; And output it
40$:	JMP	CCOUT1
;
;	Set up page number
;
GOPAG:	MOV	R3,-(SP)
	CALL	GWRD		; Get page number index
	MOV	R1,R2
	MOV	#SUBF0,R3	; Substitution buffer
	CALL	BEGBF		; Reset to beginning of buffer
	MOV	R2,R1
	CALL	FNDBF		; Get location
	BCS	10$
	CALL	GETPAG		; Get page number
10$:	MOV	(SP)+,R3	; Restore
	JMP	CCOUT1		; Return
;
;	Routine to get page number into buffer in symbolic rep.
;
GETPAG::CLR	R1
	TSTNEB	$CHPSW,20$	; No chapter ?
	MOV	APNDN,R1	; Get appendix
	BEQ	10$
	BIS	APNDSP,R1	; And format
	BR	20$
10$:	MOVB	CHPTN,R1	; Chapter number
	BIC	#^C<377>,R1	; Clear extra
	BEQ	20$		; None ?
	BIS	CHPDSP,R1	; And format
20$:	CALL	PWRD
	MOV	PAGENO,R1	; Get page number
	BNE	25$		; Not zero ?
	INC	R1		; Set it to 1
25$:	BIS	PAGDSP,R1	; Set format
	CALL	PWRD		; Save current page
	CLR	R1		; Incase no subpage
	TSTEQB	$SBPSW,30$	; No subpage ?
	MOVB	SUBPGE,R1	; Get subpage
	BIS	SUBDSP,R1	; And format
30$:	CALL	PWRD
	RETURN
;
;	Subroutine to output printable chars
;
CCSPC::	MOV	#SPC,R1		; GET SPACE
CCPRN:	TSTEQB	$ULOSW,NOUNL	; No underlining ?
	MOV	PHSPOU,R2	; Number of underlines
	CALL	CCUNL		; YES, DO IT
	JMP	FOUT		; output character
NOUNL:	ADD	PHSPOU,CPOS	; INCREMENT POSITION COUNTER
	JMP	FOUT		; OUTPUT CHAR
;
;	Do underlining
;
CCUNL:	MOV	R1,-(SP)	; SAVE CHAR
80$:	TSTB	$ULMSW
	BNE	90$		; Underline by line or sim. ?
	MOV	R2,-(SP)	; Save count
	ADD	R2,CPOS		; New position
82$:	MOV	#LPUS,R1	; GET UNDERLINE
	CALL	FOUT		; OUTPUT IT
	SUB	PHSPOU,R2	; Remaining count
	BGT	82$		; More to do ?
	MOV	(SP)+,R2	; Get count again
84$:	MOV	#BS,R1		; GET BACKSPACE
	CALL	FOUT		; OUTPUT IT
	SUB	PHSPOU,R2	; Remaining count
	BGT	84$		; More to do ?
	BR	100$
90$:	MOV	CPOS,R0		; POSITION
	CMP	R0,#ULNSZ	; TOO BIG?
	BHI	95$		; YES
	MOVB	$ULCH,UBUFF-1(R0) ; PUT IT INTO BUFFER
	CMP	R0,ULNMAX	; SMALLER DUE TO BS
	BLOS	100$		; YES, KEEP MAX
	MOV	R0,ULNMAX	; AND SAVE LAST ADDRESS
95$:	INC	CPOS
	SOB	R2,90$		; Do it for each char
100$:	MOV	(SP)+,R1	; GET SAVED CHAR
	RETURN
;
;	Output byte underlined
;
PUBYT0:	ADD	PHSP,SPCH	; Add to spacing char count
	MOVB	R1,LCH		; SAVE LAST CHARACTER
PUBYT::	TSTNEB	$UNLSW,11$	; No underline this char ?
	TSTNE	@EQSTK,11$	; Equation in progress ?
	BIC	#^C<177>,R1	; Set to proper range
	BITNEB	#CH.UNL,CHTABL(R1),11$	; Underlining not allowed ?
	BIS	#200,R1		; Mark it as underlined
11$:	JMP	PBYT		; OUTPUT CHAR
;
;	This is an equation writing routine
;	It will parse fractions written in the form:
;		{ . . . }/{. . .}
;	and using standard letter quality printer escape sequences
;	generate factions.
;
;
;	The first left brace generates:
;		1. Shift up
;		2. Multiple spaces = 0
;
;	The numerator right brace ( }/{ )
;		1. Shift down
;		2. Multiple BS
;		3. Multiple underscore
;		4. Multiple BS
;		5. Shift down
;
;	Denominator right brace
;		1. Multiple spaces ?
;		2. Shift up
;
;	EQSTK contains the following
;		Word 0	= 0
;		. . . . . . .
;		1+N = Index points to beginning of numerator
;		2+N = Shift up count
;		3+N = Vertical space occupied
;		3+N = Current spacing
;		4+N = Type (1 = Numerator, 2 = Denom.)
;		. . . . . . .
;
EQ.HS=-2		; Offset from type
EQ.VSZ=-4		; Offset to vertical size
EQ.VSP=-6		; Offset from type for horiz spacing param
EQ.AD=-8.		; Offset from type for address of output
EQ.NX=-10.		; Offset to next stack entry
;
;	Add word to equation stack
;	R0=word to add
;
STACK:	CMP	EQSTK,#EQSEN-2		; Past end of stack ?
	BHIS	EQERR3			; Yes ?
	ADD	#2,EQSTK		; Incrment stack pointer
	MOV	R0,@EQSTK		; Save value
	RETURN
EQERR3:	MOV	#EQER3,R0
	CALL	ILCMC			; Output error message
	JMP	GCIN
;
;
;	Routine to alter shifts if necessary
;
SHIFT:	CMP	R1,EQ.VSP(R5)		; Extra shift needed
	BLE	10$			; No extra needed
	MOV	R1,EQ.VSP(R5)
10$:	MOV	EQ.VSP(R5),R1		; New shift count
	CMP	R2,EQ.VSZ(R5)		; Check vertical size
	BLE	20$			; Not larger than saved ?
	MOV	R2,EQ.VSZ(R5)		; Save new one
20$:	MOV	EQ.VSZ(R5),R2		; New vertical size
	RETURN
;
;	Found left brace {
;
;
;	Service equation flags
;
GCEQN1:	TSTNEB	$EQFSW+1,NOEQ		; No equations allowed ?
	MOVB	#'(,R1			; Just in case no flag
	TSTNEB	$EQUSW,NOEQ		; Equation disabled ?
	CALL	PADIT			; Check for subscripts/superscripts
	MOV	BF.FUL(R3),R0		; And current buffer pointer
	INC	R0
	CALL	STACK			; EQ.AD
	MOV	#1,R2
	ADD	EQSPC,R2		; Plust extra
	MOV	R2,R0			; Save on stack
	CALL	STACK			; EQ.VSP
	CALL	UP			; Shift up
	CLR	R0			; Vertical size
	CALL	STACK			; EQ.VSZ
	MOV	SPCH,R0			; Save the current spacing chars
	CALL	STACK			; EQ.HS
	MOV	#1,R0			; And now the type
	CALL	STACK			; EQ.TYP
	MOV	#NXS,R4			; Character to store
	CLR	R2			; Number of times
	CALL	REPEAT
	JMP	GCIN			; Continue
NOEQ:	JMP	GCINR			; No char formation
;
;	Found right brace }
;
GCEQN2:	TSTNEB	$EQFSW+1,NOEQ		; No equations allowed ?
	MOVB	#'),R1			; In case no equation
	TSTNEB	$EQUSW,NOEQ		; Equation disabled ?
	CALL	PADIT			; Check for subscripts/superscripts
	MOV	EQSTK,R5		; Get current stack
	CMPNE	(R5),#1,10$		; End of denominator ?
	JMP	GCEQ3			; Parse End of numerator
10$:	CMPEQ	(R5),#2,11$		; End of denom ?
	JMP	EQERR4
11$:	MOV	EQ.VSP(R5),R2		; Shift back up
	CALL	UP
	MOV	SPCH,R2			; Current spacing
	SUB	EQ.NX+EQ.HS(R5),R2	; - previous spacing
	BGT	12$			; OK ?
	JMP	EQERR4			; Bad ?
12$:	SUB	EQ.HS(R5),R2		; Subtract numerator spacing
	BEQ	50$			; Done ?
	BGT	40$			; Denom bigger ?
	NEG	R2
	ADD	R2,SPCH			; Adjust spacing char count
	SUB	R2,LINBK
	MOV	R2,-(SP)		; Save
	ASR	R2			; Divide by 2
	BEQ	20$			; No spaces at end
	MOV	#NXS,R4			; Add on spaces at end
	CALL	REPEAT
20$:	SUB	R2,(SP)			; Now spacing at beginning of line
	MOV	(SP)+,R2		; Get result
	BEQ	50$			; None at beginning
	MOV	EQ.AD(R5),R1		; Buffer index for spacing
	CALL	FNDBF
30$:	CALL	ENDREP			; Skip shift down 1.
	CALL	ENDREP			; Skip BS 2.
	CALL	ENDREP			; Skip underline 3.
	MOV	EQ.HS(R5),R1		; Previous spacing
	SUB	R2,R1			; New Backspace count
	CALL	PBYT			; Save the space count
	BR	50$			; Now handle vertical spacing
40$:	MOV	R2,-(SP)		; Save count
	ASR	R2			; Divide by 2
	BEQ	45$			; No count
	MOV	EQ.NX+EQ.AD(R5),R1	; left brace output index
	CALL	FNDBF
	CALL	ENDREP			; Now have spacing count
	MOV	R2,R1			; Actual number of spaces
	CALL	PBYT
45$:	MOV	EQ.AD(R5),R1		; Get index
	CALL	FNDBF			; Get location
	CALL	ENDREP			; Skip shift param
	MOV	EQ.HS(R5),R1		; Backspace count
	ADD	R2,R1			; + spaces at beginning
	CALL	PBYT			; And save it
	CALL	ENDREP			; Now have underline repeat
	ADD	EQ.HS(R5),(SP)		; Total number of char in denom
	MOV	(SP),R1			; Actual underline size
	CALL	PBYT
	CALL	ENDREP			; Next BS
	MOV	(SP)+,R1		; Number to do
	CALL	PBYT
50$:	MOV	EQ.NX+EQ.AD(R5),R1	; Adjust the vertical spacing
	CALL	FNDBF			; Get vertical spacing repeat
	MOV	EQ.NX+EQ.VSP(R5),R1	; Adjusted vertical spacing
	MOV	R1,R2			; Save
	CALL	PBYT
	MOV	EQ.AD(R5),R1		; Denominator
	CALL	FNDBF
	DEC	R2			;
	MOV	R2,R1			; Back to line vs
	CALL	PBYT
	MOV	#4,R4			; Skip 4 params
60$:	CALL	ENDREP
	SOB	R4,60$
	MOV	EQ.VSP(R5),R1
	INC	R1			; Plus 1
	CALL	PBYT			; New vertical spacing
	MOV	EQSTK,R0		; Current stack address
	MOV	EQ.VSZ(R0),R1		; Denominator
	ADD	EQ.VSP(R0),R1		; Total denom size
	ADD	#EQ.NX,R0		; Next entry
	MOV	EQ.VSZ(R0),R2		; Numerator size
	ADD	EQ.VSP(R0),R2		; Total numerator size
	ADD	#EQ.NX,R0		; Next entry
	MOV	R0,EQSTK
	TSTNE	(R0),80$		; Equation not ended ?
	TSTEQB	$SEQSW,80$		; No separated equations ?
	BITNE	#FOTF,F.1,80$		; Footnote in progress ?
	TST	LINBK			; Past end of line ?
	BLT	80$			; Do not save size
	DEC	R1			; Size -1/2 line already accounted for
	DEC	R2			; Ditto
	CMP	R1,EQBOT		; Compare with current value
	BLE	65$			; Smaller ?
	MOV	R1,EQBOT		; Save size
65$:	CMP	R2,EQTOP		; Compare with current value
	BLE	68$			; Smaller ?
	MOV	R2,EQTOP		; Save top size
68$:	CALL	BRKSV			; Put line break here
80$:	CALL	ENDBF			; Back at end of buffer
	JMP	GCIN			; Continue
;
;	Error during text processing
;
EQERR4:	MOV	#EQER4,R0
	CALL	ILCMC			; Output error message
	JMP	GCIN			; Next char
;
;	End numerator
;
GCEQ3:	CALL	CCIN			; Get next char (look for /)
	CMPEQB	R1,#SPC,GCEQ3		; Space ?
	CMPEQB	R1,#TAB,GCEQ3		; Tab ?
	CMPNEB	R1,#'/,EQERR4		; Error in parsing ? not slash ?
10$:	CALL	CCIN			; Get next char (look for } )
	CMPEQB	R1,#SPC,10$		; Space ?
	CMPEQB	R1,#TAB,10$		; Tab ?
	CMPNEB	R1,#'{,EQERR4		; Error in parsing ? not left brace ?
	MOV	BF.FUL(R3),R0		; And current buffer pointer
	INC	R0
	CALL	STACK			; EQ.AD
	MOV	EQ.VSP(R5),R2		; Previous vertical shift
	DEC	R2			; - 1
	CALL	DOWN			; Now execute a shift down
	MOV	#1,R0
	ADD	EQSPC,R0		; Vertical shift for stack
	CALL	STACK			; EQ.VSP Save shift on stack
	CLR	R0			; Vertical size
	CALL	STACK			; EQ.VSZ
	MOV	SPCH,R0			; Current spacing
	SUB	EQ.HS(R5),R0		; Horizontal movement
	MOV	R0,R2			; Save
	BLE	EQERR4			; Bad ?
	SUB	R0,SPCH
	ADD	R0,LINBK		; Set back to old spacing char
	CALL	STACK			; EQ.HS Save it for convenience
	MOV	#2,R0			; And now the type
	CALL	STACK			; EQ.TYP
	MOV	#BS,R4			; Repeat backspace
	CALL	REPEAT
	MOV	#'_,R4			; Repeat underline
	CALL	REPEAT
	MOV	#10,R4			; Back space again
	CALL	REPEAT
	MOV	#2,R2			; Down shift to execute
	CALL	DOWN			; Now shift down
	JMP	GCIN
;
;	Pad the equation with 1/2 lines as necessary
;
PADIT:	MOV	EQSTK,R5		; Get stack location
	TSTEQ	(R5),100$		; First time thru ?
	MOV	MINVS,R2		; Subscripts
	NEG	R2			; Correct sign
	MOV	MAXVS,R1		; Plus Superscripts
	INC	R1			; Account for 1/2 line
	INC	R2			; Ditto
5$:	CMPEQ	(R5),#1,10$		; Numerator ?
	MOV	R2,-(SP)
	MOV	R1,R2			; Reverse order
	MOV	(SP)+,R1
10$:	TSTEQ	(R5),100$		; Done ?
	CALL	SHIFT			; Check if spacing is correct
	CMPEQ	(R5),#1,30$		; Current is numerator ?
	ADD	#EQ.NX,R5		; Next entry
	ADD	R2,R1			; Now is shift up
	MOV	EQ.VSZ(R5),R2		; Get size above numerator
	ADD	EQ.VSP(R5),R2		; Add shift up
	ADD	#EQ.NX,R5		; Next entry
	BR	5$
30$:	ADD	#EQ.NX,R5		; Next entry
	CMPEQ	(R5),#1,40$		; Another numerator?
	ADD	R2,R1			; Add size to shift
	CLR	R2			; Clear shift
	BR	10$
40$:	ADD	R1,R2			; Add shift to spacing
	CLR	R1
	BR	10$
100$:	CLR	MAXVS			; Maximum vertical spacing
	CLR	MINVS			; Minimum vertical spacing
	CLR	CURVS			; And clear current
	RETURN
;
;	Enter repeating char into output
;		R4=Char to repeat
;		R2=Repeat count
;
REPEAT:	MOV	#REPO,R1		; Set for repeat
	CALL	PBYT
	MOV	R2,R1			; Repeat count
	CALL	PBYT
	MOV	R4,R1			; Char to repeat
	CALL	PBYT			; Now output character
	CALL	CBYT
	RETURN
;
;	Put up/down shifts into output
;
UP:	MOV	#REPO,R1		; Get repeat char
	CALL	PBYT			; To output
	MOV	R2,R1			; Number of shifts
	CALL	PBYT
10$:	MOV	#UPTAB,R2		; Characters to transfer
20$:	MOVB	(R2)+,R1		; Get char
	BEQ	30$			; End of buffer
	CALL	PBYT			; Into output buffer
	BR	20$
30$:	CALL	PWRD			; Terminate escape + repeat
	RETURN
DOWN:	MOV	#REPO,R1		; Get repeat char
	CALL	PBYT			; To output
	MOV	R2,R1			; Number of shifts
	CALL	PBYT
10$:	MOV	#DNTAB,R2		; Characters to transfer
20$:	MOVB	(R2)+,R1		; Get char
	BEQ	30$			; End of buffer
	CALL	PBYT			; Into output buffer
	BR	20$
30$:	CALL	PWRD			; Terminate sequence
	RETURN
;
;	Subroutine to find end of repeat function
;
ENDREP:	CALL	GBYT			; Get next char in output buffer
1$:	CALL	GBYT
	BNE	1$			; Not at end of repeat
20$:	CALL	GBYT			; Begin next param
	BEQ	20$			; Another null ?
	RETURN
;
;	End equation by end of line
;
GCEQN:	CALL	BKSPI			; Again ?
	CMPNE	EQSTK,#EQSTK+2,10$	; Not at end of stack
	JMP	GCIN
10$:	JMP	EQERR4			; Bad equation
	.END
