PROCEDURE	<BUFMAN - MANAGE RUNOFF BUFFERS>,020006
;+
; 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.
;
; Abstract:	This module contains various RUNOFF buffer management
;		routines. These modules were broken out of the
;		RUNOFF mainline so as to provide ease of maintenance.
;
; System:	This module was implemented under IAS V3.0, but
;		should work on any system supporting RSX-11M.
;
; 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
;
; Modified: 17-Jul-80, -2.0.1-, Jon Berntsen
;
; Modified: 27-Aug-80, -2.0.2-, John D. Leonard
;	Added support for incremental sub/super scripting movement
;
; Modified: 05-Sep-80, -2.0.3-, John D. Leonard
;	Fixed PSTRxx and CCOUT so sub/supers work right with center and title.
;
; Modified: 12-Sep-80, -2.0.4-, John D. Leonard
;	Added support for second character set
;
; Modified: 19-Sep-80, -2.0.5-, John D. Leonard
;	Fixed bug on underlining multiple super/subscripts
;
; Modified: 15-Oct-80, -2.0.6-, John D. Leonard
;	Added OverBar a'la Underline feature
;-

	.SBTTL	Runoff Definitions

;	Global definitions

	.GLOBL	BS			; Backspace character
	.GLOBL	CAS			; Lower to upper conversion factor
	.GLOBL	CPOS			; Current position on line
	.GLOBL	DIASW			; Super/Subscript switch
	.GLOBL	ESC			; ESCAPE character
	.GLOBL	FIN			; Get character from input file
	.GLOBL	FOOTP1			; Footnote buffer header
	.GLOBL	FOTF			; Footnote active flag
	.GLOBL	FOUT			; Output character to output file
	.GLOBL	F.1			; Current state flags word
	.GLOBL	GCINP			; Saved string buffer
	.GLOBL	GCSCH			; Saved character buffer
	.GLOBL	LF			; Line feed
	.GLOBL	LIBUF			; Line input buffer
	.GLOBL	LINNSC			; Pointer to last non-spacing char.
	.GLOBL	LOBUF			; Line output buffer
	.GLOBL	LPUS			; Line printer underscore character
	.GLOBL	LWCAS			; Set case mode to lower case
	.GLOBL	METCAP			; Upper case indicator
	.GLOBL	METNHY			; No hyphenation indicator
	.GLOBL	METQSP			; Quoted space indicator
	.GLOBL	METQUO			; Quote next character indicator
	.GLOBL	METSBC			; Subscript character indicator
	.GLOBL	METSHD			; Lower case indicator
	.GLOBL	METSHU			; Upper case indicator
	.GLOBL	METSPC			; Superscript indicator
	.GLOBL	METUNL			; Underline indicator
	.GLOBL	NHLF			; Negative half line feed
	.GLOBL	NSPCH			; Pointer to last non-spacing char.
	.GLOBL	PHLF			; Positive half line feed
	.GLOBL	QTS			; Quoted space(internal rep)
	.GLOBL	SBCHS			; Superscript(internal rep)
	.GLOBL	SDBUF			; Secondary input buffer
	.GLOBL	SPC			; Space or blank character
	.GLOBL	SPCHS			; Subscript(internal rep)
	.GLOBL	S1			; Temporary string pointer
	.GLOBL	TAB			; Tab character
	.GLOBL	TFOUT			; TOC output character
	.GLOBL	ULCHS			; Underline(internal rep)
	.GLOBL	ULMCH			; Underline saved char. buffer
	.GLOBL	ULPOS			; Next avail. slot in UL buffer
	.GLOBL	UPCAS			; Set mode to upper case
	.GLOBL	UPCSW			; Upper case switch mask
	.GLOBL	WCAS			; Word capitalize conversion value
	.GLOBL	$CFLSW			; Flag capitalize switch
	.GLOBL	$GCISW			; Input from reread buffer switch
	.GLOBL	$HFLSW			; Flags hyphenate switch
	.GLOBL	$SDISW			; Input from secondary input buffer
	.GLOBL	$ULLSW			; Under line lock switch
	.GLOBL	$ULMSW			; Underline mode, Backspace


	.SBTTL	Runoff definitions(continued)

;	Globals defined in this module

	.GLOBL	CCIN			; Read character from input file
	.GLOBL	CCINUC			; Read character from input file
					; and translate to upper case.
					; or from footnote buffer
	.GLOBL	CCOUT			; Output character to output file
					; after some tests
	.GLOBL	CCSPC			; Output space to output file
	.GLOBL	GCI			; Get character from buffer
	.GLOBL	GCIN			; Get input character from buffers
	.GLOBL	INIBUF			; Initialize buffer header
	.GLOBL	NSPAC			; Output spaces to output file
	.GLOBL	PSTRAZ			; Output ASCIZ string to output file
	.GLOBL	PSTRPA			; Output a buffer to the output file
	.GLOBL	TNSPAC			; Output spaces to TOC file
	.GLOBL	WCI			; Write character in buffer
	.GLOBL	WCIFTN			; Write character in footnote buffer
	.GLOBL	WLNIN1			; Write character in line buffer


	.SBTTL	GCIN -- GET INPUT CHARACTER FROM SOURCE FILE
	CODE	BUFMAN

;	GCIN
;	GCIN will read a character from one of the following buffers:
;
;		1) The saved line buffer(GCINP),
;		2) The saved character buffer (GCSCH),
;		3) The input file buffer(HFIN),
GCIN::
	.ENABL	LSB

;	Check to see if read is to be done from saved
;	line buffer.
;	If so, read the character and return to caller.

	TSTEQB	$GCISW,GCIN3	; not rereading from buffer?
	MOV	#GCINP,R4	; Point to saved char. buffer
	CALL	GCI		; Get character from it
	.WORD	10$		; If none, then clear re-read flag
	RETURN			;

;	End of saved line buffer reached, clear flag so input
;	will come from elsewhere.

10$:	CLRB	$GCISW		; clear reread flag

;	Check to see if the character is coming from the saved
;	character buffer.
;	The saved character buffer is a 1 byte buffer. It is
;	non-zero if it contains a character and null if not.

GCIN3:	TSTNEB	GCSCH,GCIN5	; saved character?

;	Check to see if the character is coming from the
;	saved underline character buffer. If so, place it in
;	R1 and clear the buffer.
;	ULMCH is similar to GCSCH.

	.IF	NDF	A$$RAP
	MOVB	ULMCH,R1	; saved underline character?
	BEQ	GCIN5		; if eq no
	CLRB	ULMCH		; clear saved underline character
	.IFF
	MOVB	@ULMCHP,R1	; saved underliner/overbar character ?
	BEQ	GCIN5		; If eq no.
	DEC	ULMCHP		; pop off character in underline stack
	.endc
	.IF	NDF	A$$RAP
	CMPEQ	R1,#SPCHS,90$	; superscript request?
	CMPEQ	R1,#SBCHS,90$	; subscript request?
	.IFF
	CMPEQ	R1,#ULCHS,15$	; Underline character ?
	CMPEQ	R1,#OBCHS,15$	; Overbar character ?
	CMPEQ	R1,#CS2CHS,15$	; +04 font 2 request?
	MOV	R1,R4		; check super/sub range
	BIC	#3,R4		; clear bits 0-2
	CMPEQ	R4,#SPCHS,15$	; superscript request?
	CMPEQ	R4,#SBCHS,15$	; subscript request?
	.ENDC
	JMP	100$		;
	.IF	DF	A$$RAP
15$:	JMP	90$		; intermediate branch
	.ENDC

;	Get character from file. CCIN knows about GCSCH, so it
;	will fill in R1 appropriately.

GCIN5:	CALL	CCIN		; no.  get character from file.

;	Perform the appropriate case conversions for the
;	character input.

GCIN6:	BITB	#CHALC,CHATBL(R1) ; Is the character lower case?
	BEQ	30$		; No, upper case or non-alphabetic.

;	Check to see if the /UC switch has been specified. If so,
;	then force all lower case to upper case.

	BIT	#UPCSW,$INSW	; Force upper case ?
	BEQ	20$		; EQ - no
	SUB	#40,R1		; make upper case
	BR	GCINR

;	Convert case of character as necessary

20$:	SUB	WCAS,R1		; convert case if necessary
	BR	GCINR		;

;	Check for upper case character and convert case as necessary.

30$:	BITB	#CHAUC!CHALC,CHATBL(R1) ; Is the character alphabetic?
	BEQ	40$		; EQ - no
	TSTNE	WCAS,GCINR	; converting to upper case for this word?
	ADD	CAS,R1		; convert to lower case if necessary
	BR	GCINR		;

40$:	TSTEQ	$CFLSW,70$	; flags capitalize not enabled?
	CMPEQ	R1,METQSP,50$	; quoted space?
	BITB	#CHASP,CHATBL(R1) ; Is it a "normal" spacing char
				; (blank or tab)?
	BNE	50$		; NE - yes
	CMPNE	R1,#LF,60$	; not line feed?
50$:	CLR	WCAS		; clear word case conversion
60$:	CMPNE	R1,METCAP,70$	; not word capitalize?
	MOV	#40,WCAS	; set word capitalize conversion value
	BR	GCIN3		;
70$:	CMPEQ	R1,METQUO,CWR1	; quoting a character?
	CMPEQ	R1,METSHU,SHFUP	; upshift character?
	.IF	NDF	A$$RAP
	CMPEQ	R1,METSHD,SHFDN	; downshift character?
	.IFF
	CMPNE	R1,METSHD,75$	; downshift character?
	JMP	SHFDN		; yes - down shift
75$:
	.ENDC
	CMPEQ	R1,METUNL,ULCH	; underline request?
	CMPEQ	R1,METSPC,SPCH	; superscript request ?
	CMPEQ	R1,METSBC,SBCH	; subscript request ?
	.IF	DF	A$$RAP
	CMPEQ	R1,METCS2,CS2CH	; Font 2 request?
	CMPEQ	R1,METOVB,OBCH	; overbar request ?
	.ENDC
	CMPNE	R1,METILR,76$ 	; In-line comment ?
	JMP	REMARK		; yes
76$:
	.IF DF	H$$PHN
	TSTEQ	$HFLSW,80$	; flags hyphenate not enabled?
	.IF	NDF	A$$RAP
	CMPEQ	METNHY,R1,FLHYP ; flags hyphenate?
	.IFF
	CMPNE	METNHY,R1,78$	; flags hyphenate?
	JMP	FLHYP		; Yes - flags hyphenate
78$:				;
	.ENDC
	.IFTF
80$:	CMPNE	R1,METQSP,GCINR	; not quoted space?
	MOV	#QTS,R1		; set quoted space


	.SBTTL	GCINR -- Get character from re-read buffer

GCINR::
	.IF	NDF	A$$RAP
	TSTEQ	$ULLSW,100$	; underline shift-lock not on?
	.IFF
	TSTNE	$ULLSW,81$	; underline shift-lock on?
	TSTEQ	$OBLSW,100$	; overbar shift-lock not on either?
81$:
	.ENDC
	TSTNE	$ULLS1,110$	; check for after a sub or superscript
	.IF	NDF	A$$RAP
	CMPEQ	#QTS,R1,100$	; quoted space?
	.IFF
	CMPNE	#QTS,R1,83$	; not quoted space
	TSTEQ	$EQMFL,100$	; If not equation mode, don't under/overline q sp
	BR	85$		; Otherwize, under/overline quoted space
83$:
	.ENDC
	CMP	#SPC,R1		; printing character?
	BGE	100$		; if ge no
85$:
	.IF	NDF	A$$RAP
	MOVB	R1,ULMCH	; save underlined character
	.IFF
	INC	ULMCHP		; Bump pointer
	MOVB	R1,@ULMCHP	; save underlined/overbarred character
	TSTEQ	$OBLSW,86$	; Overbar not locked on
	INC	ULMCHP		; Bump pointer
	MOVB	#OBCHS,@ULMCHP	; Save overbar character in case also underlining
86$:	TSTEQ	$ULLSW,87$	; Underline not locked on
	INC	ULMCHP		; bump pointer
	MOVB	#ULCHS,@ULMCHP	; Save under line character
87$:	MOVB	@ULMCHP,R1	; return underline or overbar
	DEC	ULMCHP		; pop off character
	BR	90$		; It's non-spacing

OBCH:	MOV	#OBCHS,R1	; set to overbar character
	BR	90$
	.ENDC
ULCH:	MOV	#ULCHS,R1	; set to underline character

90$:	INC	NSPCH		; count nonspacing characters
100$:	RETURN			;

110$:	CLR	$ULLS1		; clear flag
	RETURN

	.IF	DF	A$$RAP
CS2CH:	MOV	#CS2CHS,R1	; set to font 2 character
	BR	125$
	.ENDC
SPCH:	MOV	#SPCHS,R1	; set to superscript character
	BR	120$		;
SBCH:	MOV	#SBCHS,R1	; set to subscript character
120$:
	.IF	DF	A$$RAP
	ADD	SSINC,R1	; 1/8,1/4 OR 3/8 flag
125$:
	.ENDC
	.IF	NDF	A$$RAP
	TSTEQ	$ULLSW,90$	; If no underline exit normally
	.IFF
	TSTNE	$ULLSW,130$	; Under line in effect
	TSTEQ	$OBLSW,90$	; If no underline or overbar exit normally
130$:	TSTNE	$ULLS1,90$	; If underline already set for sub/super
	.ENDC
	MOV	SP,$ULLS1	; set switch
	BR	85$		;
	.DSABL	LSB
	.IFT

	.SBTTL	FLHYP -- FLAG HYPHENATE CHARACTER

; flag hyphenate character

FLHYP:	CALL	GCIN		; get next character with translate
	BITB	#CHAUC!CHALC,CHATBL(R1) ; Alphabetic character?
	BEQ	GCINR		; If EQ no
	BISB	#200,R1		; disable hyphenation on this word
	BR	GCINR		;
	.ENDC


	.SBTTL	SPECIAL CASES OF INPUT CHARACTER

CWR1:	CALL	CCIN		; read character  no translation
	BR	GCINR		; and return it.  maybe underlined

; more special cases of get-character routine

	.ENABL	LSB
SHFUP:	CALL	CCIN		; read a character
	CMPEQ	R1,METUNL,ULMON	; lock on underline?
	CMPEQ	R1,METSPC,SPMON	; superscript lock on ?
	CMPEQ	R1,METSBC,SBMON	; subscript lock on ?
	.IF	DF	A$$RAP
	CMPEQ	R1,METCS2,CS2MON ; font 2 lock on ?
	CMPEQ	R1,METOVB,OBMON	; Lock on overbar ?
	.ENDC
	CMPEQ	R1,METILR,REMARK ; In-line remarks ?
	CMPNE	R1,METSHU,20$	; not double upshift?
	CALL	UPCAS		; set upper case

10$:	JMP	GCIN3		; and go read another character

;	Process in-line comments
;
;	This change allows in line comments of the form:
;
;	text	^!comment  <cr>
; or	text	^!comment  !
;

REMARK:	CALL	CCIN		; Gobble character
	CMPEQ	R1,METILR,10$	; End of comment ?
	CMPNE	R1,#CR,REMARK	; At end of line yet ?
	RETURN			; If so, then return

20$:	BITB	#CHAUC!CHALC,CHATBL(R1) ; Alphabetic character?
	BEQ	GCIN6A		; If EQ - no
	BITB	#CHALC,CHATBL(R1) ; Lower case alphabetic?
	BEQ	65$		; If EQ - no
	BIC	#40,R1		; Make into an upper case letter.
	BR	65$		; And leave.

SHFDN:	CALL	CCIN		; get another character
	CMPEQ	R1,METUNL,ULMOF	; unlock underline?
	CMPEQ	R1,METSPC,SPMOF	; superscript lock off ?
	CMPEQ	R1,METSBC,SBMOF	; subscript lock off ?
	.IF	DF	A$$RAP
	CMPEQ	R1,METCS2,CS2MOF ; Font 2 lock off ?
	CMPEQ	R1,METOVB,OBMOF	; Lock overbar off ?
	.ENDC
	CMPNE	R1,METSHD,60$	; not second downshift?
	CALL	LWCAS		; set lower case
	BR	10$		;

60$:	BITB	#CHAUC!CHALC,CHATBL(R1) ; Is it alphabetic?
	BEQ	GCIN6A		; If EQ - no
	BITB	#CHAUC,CHATBL(R1) ; Is it upper case?
	BEQ	65$		; No, just leave.
	BIS	#40,R1		; Yes, make it lower case.
65$:	JMP	GCINR		; And leave.
GCIN6A:	JMP	GCIN6		;

ULMON:	MOV	SP,$ULLSW	; underline locked on
	BR	10$
ULMOF:	CLR	$ULLSW		; underline locked off
	.IF	DF	A$$RAP
	TSTNE	$OBLSW,10$	; If overbar lock on don't clear flag yet
	CLR	$ULLS1		; Clear sub/super underline flag
	.ENDC
	BR	10$		;
	.IF	DF	A$$RAP

OBMON:	MOV	SP,$OBLSW	; Overbar locked on
	BR	10$
OBMOF:	CLR	$OBLSW		; Overbar locked off
	TSTNE	$ULLSW,10$	; don't clear flag if underline in effect
	CLR	$ULLS1		; clear flag
	BR	10$		;
	.ENDC

SBMOF:	
SPMON:	BITEQ	#DIASW,$INSW,10$ ; if not diablo, then skip
	MOV	#ESC,R1		; lock on superscript
	CALL	WLNIN1		;
	MOV	#NHLF,R1	;
	.IF	DF	A$$RAP
	ADD	SSINC,R1	;
	.ENDC
	BR	100$		;

SPMOF:
SBMON:	BITEQ	#DIASW,$INSW,10$ ; if not diablo, then quit
	MOV	#ESC,R1		; lock on subscript
	CALL	WLNIN1		;
	MOV	#PHLF,R1	;
	.IF	DF	A$$RAP
	ADD	SSINC,R1	;
	.ENDC
	BR	100$		;
	.IF	DF	A$$RAP
	
CS2MON:	MOV	#ESC,R1		; Lock on font 2
	CALL	WLNIN1		;
	MOV	#CS2,R1		; Indicate font 2
	BR	100$		;
	
CS2MOF:	MOV	#ESC,R1		; Set back to font 1, font 2 off
	CALL	WLNIN1		;
	MOV	#CS1,R1		; Indicate font 1
	BR	100$		;
	.ENDC
	
100$:	CALL	WLNIN1		;
	ADD	#2,LINNSC	;
	BR	10$
	.DSABL	LSB

	.SBTTL	NSPAC -- OUTPUT SPACES TO OUTPUT FILE
	.ENABL	LSB
;
; routine to output spaces to file
;
;	R2 has count of spaces to output

NSPAC::	DEC	R2		; any more spaces to output?
	BLT	10$		; if lt no
	CALL	CCSPC		; output a space
	BR	NSPAC		;
10$:	RETURN			; And return.

	.SBTTL	TNSPAC -- OUTPUT SPACES TO TOC FILE

TNSPAC::DEC	R2		; any more spaces to output ?
	BLT	10$		; if lt, no
	MOVB	#40,R1		; set to output a space
	CALL	TFOUT		; output a space
	BR	TNSPAC		;

	.SBTTL	PSTRPA -- OUTPUT A STRING TO THE OUTPUT FILE
;
; routines to output a string to the output file
;
;	R4 - Pointer to buffer descriptor
;	S1 - Pointer to next character to output
;
;	-2,0.3- Fixed so sub/superscript work with CCOUT when called
;	from PSTRPA or PSTRAZ.

PSTRPA:: MOV	BF.ADR(R4),S1	; Point to the string
	CLRB	@BF.PTR(R4)	; Make it an ASCIZ string
	MOV	R4,-(SP)	; Save R4

	CALL	PSTRAZ		; Output the string

	MOV	(SP)+,R4	; Restore R4
	MOV	BF.ADR(R4),BF.PTR(R4) ; Reset buffer
	CLR	BF.LEN(R4)	; And the length word
	RETURN			; Return to caller

	.SBTTL	PSTRAZ -- OUTPUT AN ASCIZ STRING TO THE OUTPUT FILE

PSTRAZ::
	COMB	PSTFLG		; Show CCOUT coming from PSTRxx
15$:
	MOVB	@S1,R1		; get a character
	BEQ	20$		; if eq end of string
	CALL	CCOUT		; output to file
	TSTEQB	@S1,20$		; May have been updated by CCOUT
	INC	S1		; point to next character
	BR	15$		; loop for whole string
20$:
	CLRB	PSTFLG		; Reset PSTRxx flag for CCOUT
	RETURN			; Return to caller
	.DSABL	LSB

	.SBTTL	CCOUT -- OUTPUT CHARACTER TO OUTPUT FILE
;
; subroutine to output character to file, after some tests
;

	.ENABL	LSB
CCOUT::	SWAB	CCOUTT		; swap old character
	MOVB	R1,CCOUTT	; put in new character
	CMPNE	R1,#ULCHS,10$	; not underline character?
	.IF	NDF	A$$RAP
	TSTEQB	$ULMSW,110$	; by line?
	.ENDC
	.IF	DF	A$$RAP
	TSTNEB	$ULMSW,5$	; by line
	JMP	110$		;
5$:
	.ENDC
	MOV	#LPUS,R1	; convert to output underline
	CALL	FOUT		; yes, send underline
	MOV	#BS,R1		; and follow with backspace
	JMP	FOUT		; Output backspace do not count character

10$:
	.IF	DF	A$$RAP
	CMPNE	R1,#OBCHS,15$	; Not overbar character
	JMP	115$		;

15$:
	CMPNE	R1,#BS,17$	; Not backspace ?
	SUB	#2,CPOS		; Back up carriage position indicator 2 half-spaces
	JMP	FOUT		; Put out the character

17$:
	.ENDC
	CMPNE	R1,#QTS,20$	; not quoted space?
	.IF	DF	A$$RAP
	TSTEQ	$EQMFL,CCSPC	; No half spaces if not in .EQ mode
	CALL	GMIN		; Graph mode to space in 1/60 in.
	MOVB	HSPACE,R0	; # of 1/60" increments for half space
	MOV	#SPC,R1		; space character
18$:	CALL	FOUT		;
	SOB	R0,18$		; Loop till done
	CALL	GMOUT		; exit graph mode
	SWAB	HSPACE		; swap half-space alternating counts
	INC	CPOS		; bump carriage position 1 half-space
	RETURN
	.ENDC

CCSPC::	MOV	#SPC,R1		; make real space
	.IF	NDF	A$$RAP
	BR	100$
	.ENDC
	.IF	DF	A$$RAP
	JMP	100$		; Address out of range
	.ENDC
20$:
	.IF	NDF	A$$RAP
	CMPNE	R1,#SPCHS,60$	; not superscript ??
	.ENDC
	.IF	DF	A$$RAP
	MOV	R1,R2		; save character
	BIC	#3,R2		; clear low order bits if s/s inc
	CMPNE	R2,#SPCHS,60$	; not superscript ??
	.ENDC
	BITEQ	#DIASW,$INSW,30$ ; not diablo, then skip
	.IF	DF	A$$RAP
	MOV	R1,R2		; get increment count in low order bits
	BIC	#177774,R2	;
	BNE	25$		; 1/8 line increments
	MOV	#<DIVPL/2>,R2	; Half line
25$:	SUB	R2,VPOS		; Paper moved down
	MOV	R2,-(SP)	; Save for re-position later
	CALL	SKIPDN		; Send the control sequence
	.ENDC
	.IF	NDF	A$$RAP
	MOV	#ESC,R1		; set up to
	CALL	FOUT		; output an
	MOV	#NHLF,R1	; esc-d
	CALL	FOUT		; to the diablo
	.ENDC
30$:
	TSTNEB	PSTFLG,32$	; Called from a PSTRxx routine ?
	MOV	#LOBUF,R4	; No, point to output line buffer
	CALL	GCI		; Get character from line buffer
	.WORD	40$		; None left
	BR	35$		; Output the character
32$:
	TSTEQB	@S1,40$		; End of string ?
	INC	S1		; No, update pointer
	MOVB	@S1,R1		; Get next character from S1 for PSTRxx
	BEQ	40$		; eq if end of string
35$:
	CALL	CCOUT		; Output to file

	.IF	NDF	A$$RAP
40$:	BITEQ	#DIASW,$INSW,120$ ; if not diablo, skip
	.ENDC
	.IF	DF	A$$RAP
40$:	BITNE	#DIASW,$INSW,41$ ; if not diablo, skip
	JMP	120$		; Address out of range
41$:
	.ENDC
	.IF	DF	A$$RAP
	MOV	(SP)+,R2	; Get increment count
	ADD	R2,VPOS		; Paper moved up
	CALL	SKIPUP		; Send the control sequence
	RETURN			;
	.ENDC
	.IF	NDF	A$$RAP
	MOV	#ESC,R1
	CALL	FOUT
	MOV	#PHLF,R1
	JMP	FOUT
	.ENDC

60$:
	.IF	NDF	A$$RAP
	CMPNE	R1,#SBCHS,95$	; not superscript ??
	.ENDC
	.IF	DF	A$$RAP
	MOV	R1,R2		; save character
	BIC	#3,R2		; clear low order bits if s/s inc
	CMPEQ	R2,#SBCHS,62$	; superscript ??
	JMP	220$		; not superscript - check for font 2
62$:
	.ENDC
	BITEQ	#DIASW,$INSW,70$ ; if not diablo, then skip
	.IF	DF	A$$RAP
	MOV	R1,R2		; get increment count in low order bits
	BIC	#177774,R2	;
	BNE	65$		; eq means half line feed
	MOV	#<DIVPL/2>,R2	; # of 1/8 lines for half line
65$:	ADD	R2,VPOS		; Positive line feeds
	MOV	R2,-(SP)	; Save for reposition later
	CALL	SKIPUP		; Sent the control sequence
	.ENDC
	.IF	NDF	A$$RAP
	MOV	#ESC,R1
	CALL	FOUT
	MOV	#PHLF,R1
	CALL	FOUT
	.ENDC
70$:
	TSTNEB	PSTFLG,72$	; Called from a PSTRxx routine ?
	MOV	#LOBUF,R4	; No, point to output line buffer
	CALL	GCI		; Get character from line buffer
	.WORD	80$		; None left
	BR	75$		; Output the character
72$:
	TSTEQB	@S1,80$		; End of string ?
	INC	S1		; No, update pointer
	MOVB	@S1,R1		; Get next character from S1 for PSTRxx
	BEQ	80$		; eq if end of string
75$:
	CALL	CCOUT		; Output to file

80$:	BITEQ	#DIASW,$INSW,120$ ; if not diablo, then skip
	.IF	DF	A$$RAP
	MOV	(SP)+,R2	; Get increment count
	SUB	R2,VPOS		; Adjust VPOS for superscript re-position
	CALL	SKIPDN		; Move paper back down
	RETURN
	.ENDC
	.IF	NDF	A$$RAP
	MOV	#ESC,R1
	CALL	FOUT
	MOV	#NHLF,R1
	JMP	FOUT
	.ENDC

95$:	CMPEQ	R1,#ESC,105$	; Locked on superscript or subscript
	CMPB	#ESC,CCOUTT+1	; last character an ESC
	BNE	1000$		; no, skip tests
	.IF	NDF	A$$RAP
	CMPEQ	R1,#PHLF,105$	; just output character
	CMPEQ	R1,#NHLF,105$	;
	.ENDC
	.IF	DF	A$$RAP
	MOV	R1,R2		; Save character
	CMPEQ	R1,#<PHLF>,980$	; Half line feed ?
	CMPEQ	R1,#<PHLF+1>,98$ ;  check for V, W, or X
	CMPEQ	R1,#<PHLF+2>,98$ ;
	CMPEQ	R1,#<PHLF+3>,98$ ;
	CMPEQ	R1,#<NHLF>,960$	; Negative half line feed
	CMPEQ	R1,#<NHLF+1>,96$ ;   Check for E, F, or G
	CMPEQ	R1,#<NHLF+2>,96$ ;
	CMPEQ	R1,#<NHLF+3>,96$ ;
	BR	105$

; Put out the incremental superscript shift in 1/8 line increments

960$:	SUB	#<DIVPL/2>,VPOS	; Adjust for negative half line feed
	BR	105$		;
96$:
	SUB	#NHLF,R2	; Get increment count - subtract 'D'
	SUB	R2,VPOS		; Adjust vertical position counter
	CALL	GMIN1		; Escape present in file
97$:	MOV	#ESC,R1		;
	CALL	FOUT
	MOV	#LF,R1		;
	CALL	FOUT		;
	SOB	R2,97$		; loop till done
	CALL	GMOUT		; Exit graph mode
	RETURN

; Put out the incremental subscript shift in 1/8 line increments

980$:	ADD	#<DIVPL/2>,VPOS	; Positive half line feed
	BR	105$		;
98$:
	SUB	#PHLF,R2	; get increment count, subtract 'U'
	ADD	R2,VPOS		; Adjust vertical position for pos line feeds
	CALL	GMIN1		; Escape present
	MOV	#LF,R1		;
99$:	CALL	FOUT		;
	SOB	R2,99$		; loop till done
	CALL	GMOUT		; Exit graph mode
	RETURN

;	Check CPOS against OBLPOS (over bar carriage position) and
;	update the overbar vertical position if CPOS is less than or
;	equal to OBCPOS. CPOS could be less if backspaces are in the
;	input.

1000$:
	CMPEQ	OBPOS,#OBPBF,100$	; Skip test if no overbars specified yet
	CMP	CPOS,OBCPOS	;
	BGT	100$		; Don't update overbar vertical position
	DEC	OBPOS		; Point to vertical position
	CMPB	@OBPOS,VPOS	; If current VPOS less than last overbar
	BLE	1010$		; vertical position - don't update
	MOVB	VPOS,@OBPOS	; otherwise update the overbar vertical
1010$:	INC	OBPOS		; Restore OBPOS pointer
	.ENDC

100$:	ADD	#2,CPOS		; count position of carriage
105$:	JMP	FOUT		; output character
110$:	MOVB	CPOS,@ULPOS	; into underline buffer
	INC	ULPOS		; step buffer pointer  (should check it)
	.IF	DF	A$$RAP
	BR	120$


115$:	CMP	CPOS,OBCPOS	; Has the carriage advanced
	BLE	120$		; No, must have been backspaces
	MOVB	CPOS,@OBPOS	; Enter carriage position in overbar buffer
	INC	OBPOS		; Point to vertical allignment byte
	CLRB	@OBPOS		; Assume vertical one line until character is
				; output
	INC	OBPOS		; Update pointer to overbar buffer
	MOV	CPOS,OBCPOS	; Remember last overbar Carriage position
	.ENDC
120$:	RETURN			;
	.IF	DF	A$$RAP
220$:
	CMPNE	R1,#CS2CHS,95$	; not font 2 ??
	MOV	#ESC,R1		; set up to
	CALL	FOUT		; output an
	MOV	#CS2,R1		; esc-2
	CALL	FOUT		; to the diablo
	TSTNEB	PSTFLG,232$	; Called from a PSTRxx routine ?
	MOV	#LOBUF,R4	; No, point to output line buffer
	CALL	GCI		; Get character from line buffer
	.WORD	240$		; None left
	BR	235$		; Output the character
232$:
	TSTEQB	@S1,240$	; End of string ?
	INC	S1		; No, update pointer
	MOVB	@S1,R1		; Get next character from S1 for PSTRxx
	BEQ	240$		; eq if end of string
235$:
	CALL	CCOUT		; Output to file

240$:
	MOV	#ESC,R1
	CALL	FOUT
	MOV	#CS1,R1		; Back to font 1
	JMP	FOUT
	.ENDC
	.DSABL	LSB

	.SBTTL	GMIN/GMOUT - graph mode in/out for Diablo

GMIN::
	MOV	#ESC,R1		; set for graph mode
	CALL	FOUT		;
GMIN1::	MOV	#GMI,R1		; graph mode in character
	CALL	FOUT		;
;
;	See if 2 characters preceding <esc><enter graph mode> were
;	<esc><exit graph mode>. If so back up the HFOUT buffer pointers.
;	This will save all the extra in/out gragh mode escape sequences
;	when sub/superscripts of the form @@@@super are used.
;
	CMP	#4,HFOUT+BF.LEN	; at least 4 characters in buffer ?
	BGT	20$		; No
	MOV	HFOUT+BF.PTR,R1	; Point to current position and check
	CMPNEB	#ESC,-4(R1),20$	; for <escape> followed by
	CMPNEB	#GMO,-3(R1),20$	;	<gmo>, exit graph mode. If so
	SUB	#4,HFOUT+BF.PTR	; Back up past exit and re-enter characters
	SUB	#4,HFOUT+BF.LEN	;	since they are redundant.
20$:
	RETURN

GMOUT::
	MOV	#ESC,R1		; exit graph mode
	CALL	FOUT		;
	MOV	#GMO,R1		;
	CALL	FOUT
	RETURN

	.SBTTL	CCIN - READ INPUT FROM OTHER SOURCE

; routine to read input from file or footnote as appropriate

CCIN::	MOVB	GCSCH,R1	; any character saved from earlier pass?
	BNE	30$		; NE - Process saved character
	TSTEQB	$SDISW,20$	; input not from secondary buffer?
	MOV	#SDBUF,R4	; Point to secondary buffer
	CALL	GCI		; get character from buffer
	.WORD	10$		; NONE, Get some from input file
	RETURN			;

10$:	CLRB	$SDISW		; clear input from secondary buffer
20$:	BITNE	#FOTF,F.1,40$	; characters coming from footnote?
	CALL	FIN		; no.  read from file
	RETURN			;

30$:	CLRB	GCSCH		; clear saved character
	RETURN			;

40$:	MOV	#FOOTP1,R4	; get character from footnote string
	CALL	GCI		; get the character
	.WORD	50$		; none left, -- fatal error!!!
 	RETURN			;

50$:	FATAL	HALTM		; give the halt message and restart
;
CCINUC::
	CALL	CCIN		; Input the character.
	BITB	#CHALC,CHATBL(R1) ; Is it a lower case letter?
	BEQ	10$		; No - just return.
	BICB	#40,R1		; Yes - make it upper case.
10$:	RETURN			; And return to the caller.

	.SBTTL	GCI - GET CHAR. AND INC. PNTRS
;
;	GCI -- Get character from input buffer pointed to by R4
;
;	If there are no characters left in the buffer, then
;	return is taken to the address specified in the word
;	immediately following the call. Else return is to one
;	word beyond call.
;
;	Example:
;
;		MOV	#BUFHDR,R4	; Point to input buffer
;		CALL	GCI		; Get a character
;		.WORD	ERR		; Nothing there, error
;		TST	...		; etc...
;
GCI::	TST	BF.LEN(R4)	; Anything there ?
	BLE	20$		; LE - then nothing there
	CLR	R1		; Initialize for character insert
	BISB	@BF.PTR(R4),R1	; Insert character, no sign extend
	INC	BF.PTR(R4)	; Point to next character in buffer
	DEC	BF.LEN(R4)	; One less from length
	ADD	#2,(SP)		; Return success
10$:	RETURN			;

20$:	MOV	@(SP),(SP)	; set skip return
	CLR	BF.LEN(R4)	; Reset length
	BR	10$		; And return
;
;	WCIFTN -- Write character into footnote buffer
;
WCIFTN::MOV	#FOOTP1,R4	; point to footnote descriptor
	BR	WCI		;
;
;	WLNIN1 -- Write character into line buffer
;
WLNIN1::MOV	#LIBUF,R4	; standard arg
;
;	WCI -- Write character into buffer specified by R4
;	
WCI::	CMP	BF.PTR(R4),BF.END(R4) ; At end of buffer ?
	BHIS	10$		; HIS - Then FATAL error
	MOVB	R1,@BF.PTR(R4)	; Store byte in buffer
	INC	BF.PTR(R4)	; Point to next available word
	INC	BF.LEN(R4)	; Keep count of chars.
	CLC			; Say it worked
	RETURN			;

10$:	SEC			; Indicate error
	RETURN			;


	.sbttl	INIBUF -- Initialize buffer header

;+
;	This module will initialize a buffer header prior to use.
;
;	On entry, R4 points to the buffer header to be initialized.
;	all registers are preserved.
;-

INIBUF:: MOV	BF.ADR(R4),BF.PTR(R4)	; Initialize pointer
	CLR	BF.LEN(R4)		; Initialize length
	RETURN				; Return to caller


	.END
