	.title	RNDYN
	.ident	'BL1.0'
	.ifndf	RT11
	.MCALL	EXTK$S
	.ENDC
;
;	The symbol $DEBUG is enabled for complte dynamic subroutine checking
; It is off for normal operation since it slows down the routines.
;$DEBUG=1
;
;	The following routines are designed to handle buffers in dynamic
; pool memory. The data should be accessed via these routines. The offset
; BF.FUL is the index to your data bytes. The BF.ADD always points to the
; current byte (one accessed last by GBYT or PBYT). All data in buffers should
; be accessed via these routines. The FNDBF,BEGBF routines set the
; current data index (BF.FUL) so you may use GBYT or GWRD to get the data. You
; may access the current byte via the offset BF.ADD,when BF.FUL is non zero,
; but no other bytes
; may be accessed directly. The routine RSTBF, and ENDBF set the index and then
; set up the buffers for input via PBYT,PWRD. After BEGBF,FNDBF reading past 
; past the end of the data is inhibited. If CARRY is set the routine failed.
; CLRBF resets all pointers, deallocates all dynamic memory and sets the
; buffer chain ready for input.
;
BFSIZ	== 200		; 128. BYTES OF DATA (MUST BE POWER OF 2)
BFMSK	= 177		; BUFFER SIZE MASK
;
;		R3=BUFFER HEADER
;		R1=DATA BYTE TO PUT/GET/FIND
;		R0=DESTROYED BY THESE ROUTINES
;
;	ROUTINE TO CLEAR BUFFER FOR MORE DATA
;		EXTRA BUFFERS ARE RETURNED TO POOL
;
	.psect	$CODE,RO,LCL,CON,I
CLRBF::
	.IFDF	$DEBUG
	TST	BF.CNT(R3)	; *** DEBUG
	BGE	2$		; *** DEBUG
1$:	CALL	HLTER		; *** DEBUG
2$:	TST	BF.FUL(R3)	; *** DEBUG
	BLT	1$		; *** DEBUG
	.ENDC
	MOV	#BFSIZ,BF.CNT(R3) ; SET UP COUNT
	CLR	BF.FUL(R3)	; RESET INDEX
	CLR	BF.MAX(R3)	; RESET DATA RESIDENT
	CLR	BF.SPC(R3)	; clear spacing char count
	CLR	BF.VSP(R3)	; Clear vertical spacing
	CLR	BF.HED(R3)	; Clear header
	MOV	BF.BEG(R3),R0	; GET HEAD OF CURRENT BUFFER CHAIN
	MOV	R0,BF.CAD(R3)	; INTO CURRENT BUFFER ADDRESS
	MOV	R0,BF.ADD(R3)	; INTO DATA ADDRESS
	ADD	#BFLNK,BF.ADD(R3)	; POINTS TO FIRST BYTE-1
RETBF:	MOV	BF.CAD(R3),R0	; Current buffer
	TSTEQ	(R0),10$	; No more in chain ?
	MOV	LNKHD,@BF.END(R3) ; ADD BUFFER POOL TO END OF CHAIN
	MOV	(R0),LNKHD	; PUT COMPLETE CHAIN INTO POOL
	MOV	R0,BF.END(R3)	; LAST = current BUFFER
	CLR	(R0)		; AND NO FOREWARD LINK
10$:
	RETURN
;
; RSTBF
;	ROUTINE TO SET REQUESTED LOCATION AS END OF BUFFER READY FOR INPUT
;
; ENDBF
;	SET TO END OF BUFFER + MADE READY FOR PUTTING TO BUFFER
;
ENDBF::	MOV	BF.MAX(R3),R1	; LOCATION TO GO TO
	.IFDF	$DEBUG
	CALL	TEST		; *** DEBUG
	.ENDC
	CMP	R1,BF.FUL(R3)	; is R1 really the end?
	BHIS	RSTBF		; yes
	MOV	BF.FUL(R3),R1	; no get real end
RSTBF::	CALL	FNDBF		; GO TO IT
	CLR	BF.MAX(R3)	; CLEAR DATA MAX
	MOV	#BFSIZ,BF.CNT(R3) ; BUFFER SIZE
	SUB	R1,BF.CNT(R3)	; ADJUST COUNT TO BUFFER SIZE
	.IFDF	$DEBUG
	CALL	TEST		; *** DEBUG
	.ENDC
	BR	RETBF

;
;	ROUTINE SETS POINTER TO START OF BUFFER FOR GETTING DATA
;		IF BUFFER HAS NO DATA MAX SET, MAX=CURRENT INDEX
;
BEGBF::
	.IFDF	$DEBUG
	CALL	TEST		; *** DEBUG
	.ENDC
	MOV	BF.BEG(R3),R0	; FIRST BUFFER
	MOV	R0,BF.CAD(R3)	; IS CURRENT ONE
	ADD	#BFLNK,R0	; POINTS TO DATA-1
	MOV	R0,BF.ADD(R3)	; SAVED
	MOV	BF.MAX(R3),R0	; MAX DATA SET?
	CMP	R0,BF.FUL(R3)	; GREATER THAN CURRENT
	BHIS	10$		; YES
	MOV	BF.FUL(R3),R0	; TOTAL DATA IN BUFFER
	MOV	R0,BF.MAX(R3)	; SET SIZE TO MAX DATA SIZE
10$:	CLR	BF.FUL(R3)	; CLEAR INDEX
	CMP	R0,#BFSIZ	; SMALLER THAN BUFFER SIZE?
	BLOS	20$		; YES
	MOV	#BFSIZ,R0
20$:	MOV	R0,(R3)		; SET COUNT
	.IFDF	$DEBUG
	CALL	TEST		; *** DEBUG
	.ENDC
	RETURN

;
;	GETS NEXT BYTE FROM BUFFER
;		R1=data
;		C	= set if no data available
;		Z	= set if R1 is zero
;		N	= set if Byte R1 is negative
;		V	= undefined
;
GBYT2::	MOV	R2,R1		; Address of header
	BR	GBYT1
GBYT::	MOV	R3,R1		; FOR GBYT1
;
;	SPECIAL PURPOSE ROUTINE 
;		R1=HEADER (INPUT)
;		R1=DATA BYTE (OUTPUT)
;
GBYT1::	DEC	(R1)+		; DECREMENT COUNT
	BLT	20$		; Nothing in buffer ?
	INC	(R1)+		; INCREMENT INDEX
	INC	(R1)		; NEXT BYTE
	MOVB	@(R1),R1	; GET BYTE
	CLC
	RETURN
20$:	INC	-(R1)		; Restore count to zero
	BLT	50$		; Bad CNT
	CMP	BF.FUL(R1),BF.MAX(R1); Compare number of chars with max
	BEQ	40$		; At end of buffers ?
	BHI	50$		; ERROR ?????
	MOV	BF.CAD(R1),R0	; GET CURRENT BUFFER
	MOV	(R0),R0		; GET NEXT BUFFER IN CHAIN
	BEQ	50$		; NONE ??
	MOV	BF.MAX(R1),(R1)	; NUMBER OF BYTES TOTAL
	SUB	BF.FUL(R1),(R1)	; LESS INDEX=REMAINING
	CMP	(R1),#BFSIZ	; IS IT OK
	BLOS	30$		; YES
	MOV	#BFSIZ,(R1)	; NO, MAKE IT FULL BUFFER SIZE
30$:	MOV	R0,BF.CAD(R1)	; NEW CURRENT BUFFER
	ADD	#BFLNK,R0		; POINTS TO BYTE IN FRONT OF FIRST
	MOV	R0,BF.ADD(R1)	; SAVE ADDRESS
	.IFDF	$DEBUG
	MOV	R3,-(SP)	; *** DEBUG
	MOV	R1,R3		; *** DEBUG
	CALL	TEST		; *** DEBUG Test the params
	MOV	(SP)+,R3	; *** DEBUG
	.ENDC
	BR	GBYT1		; AND GET THE BYTE FINALLY
40$:	CLR	R1
	SEC
	RETURN
50$:	CALL	HLTER		; bad count

;
;	PUTS NEXT BYTE INTO BUFFER
;
PBYT::	MOV	R3,R0		; BUFFER HEADER
	.IFDF	$DEBUG
	CALL	TEST		; *** DEBUG
	.ENDC
	DEC	(R0)+		; DECREMENT REMAINDER COUNT
	BLT	10$		; YES, TRY TO ALLOCATE ANOTHER
	INC	(R0)+		; INCREMENT INDEX
	INC	(R0)		; INCREMENT ADDRESS
	MOVB	R1,@(R0)	; SAVE BYTE
	CLC
	RETURN
10$:	BITEQ	#BFMSK,BF.FUL(R3),11$ ; legal end of buffer?
	CALL	HLTER		; NO NO NO
11$:	MOV	BF.CAD(R3),R0	; CURRENT ADDRESS
	MOV	(R0),R0		; ANOTHER IN CHAIN?
	BNE	20$		; YES, USE IT
	MOV	LNKHD,R0	; GET BUFFER FROM POOL?
	BEQ	30$		; NONE!
	MOV	(R0),LNKHD	; REMOVE IT FROM POOL
	CLR	(R0)		; NO FOREWARD LINK
	MOV	BF.END(R3),2(R0) ; BACKWARD LINK
	MOV	R0,BF.END(R3)	; MAKE THIS LAST BUFFER
	MOV	R0,@BF.CAD(R3)	; FOREWARD LINK
20$:	MOV	#BFSIZ,(R3)	; NEW COUNT
	MOV	R0,BF.CAD(R3)	; NEW CURRENT BUFFER
	ADD	#BFLNK,R0		; POINTS TO BYTE IN FRONT OF FIRST
	MOV	R0,BF.ADD(R3)	; SAVE ADDRESS
	.IFDF	$DEBUG
	CALL	TEST		; *** DEBUG
	.ENDC
	BR	PBYT		; AND GET THE BYTE FINALLY
30$:
	.ifndf	RT11
	CALL	EXTEND		; try to extend memory
	BCC	10$		; success
	.ENDC
	MOV	#12.,R0		; No more memory avilable message
	JMP	ILINP		; KILL KILL KILL

;
;	ROUTINE GETS 1 WORD FROM BUFFERS
;		R1=data
;		C	= set if no data
;		N,Z	correspond to value in R1
;
GWRD::	CALL	GBYT		; GET LOWER BYTE
	MOV	R1,-(SP)	; SAVE IT
	CALL	GBYT		; NEXT UPPER
	MOVB	R1,1(SP)
	MOV	(SP)+,R1	; GET RESULT
	RETURN
;
;	ROUTINE TO SAVE 1 WORD
;
PWRD::	CALL	PBYT		; SAVE LOWER BYTE
	SWAB	R1		; SWAP BYTES
	CALL	PBYT		; SAVE UPPER
	SWAB	R1
	RETURN
;
;	extend the available pool
;
	.ifndf	RT11
EXTEND:	EXTK$S	#5
	BCC	10$
	RETURN
10$:	ADD	#500,XTOP	; readjust top for extend
	.endc
;
;	subroutine to set up linked list of dynamic buffers
;
LNKSET:: MOV	XBOT,R0		; save value
	ADD	#BFSIZ+6,XBOT	; raise bottom
	BCS	40$		; done
	CMP	XBOT,XTOP	; too big
	BHIS	40$		; yes
	MOV	LNKHD,(R0)	; Save current linked buffer chain
	MOV	R0,LNKHD	; put current buffer at head
	BR	LNKSET		; try another
40$:	SUB	#BFSIZ+6,XBOT	; restore
	CLC
	RETURN

;
;	SETS POINTERS TO BUFFER LOCATION SPECIFIED IN R1
;		C	SET if bad location specified
;		C	CLEAR if good location
;		IF MAX IS NOT SET	MAX=CURRENT INDEX
;
FNDBF::	CMPNE	R3,BUFADD,1$	; Not primary input buffer?
;
;	Section for input buffer only
;
	CMP	R1,BF.MAX(R3)	; ADDRESS TOO BIG?
	BHI	15$		; Yes ?
	MOV	BF.MAX(R3),BF.CNT(R3) ; MAX SIZE
	SUB	R1,BF.CNT(R3)	; NOW REMAINING SIZE
	MOV	BF.CAD(R3),BF.ADD(R3) ; START OF BUFFER
	ADD	#BFLNK,BF.ADD(R3)	; POINTS TO DATA-1
	ADD	R1,BF.ADD(R3)	; CURRENT ADDRESS
	MOV	R1,BF.FUL(R3)	; NEW LOCATION
	CLC			; Success !!
	RETURN
;
;	Section for all other buffers
;
1$:
	.IFDF	$DEBUG
	CALL	TEST		; *** DEBUG
	.ENDC
	CMP	BF.FUL(R3),BF.MAX(R3)	; CURRENT BIGGER THAN MAX?
	BLOS	10$		; NO
	MOV	BF.FUL(R3),BF.MAX(R3) ; RESET MAX
10$:	CMP	R1,BF.MAX(R3)	; GREATER THAN CURRENT
	BLOS	20$		; NO
15$:	SEC
	RETURN			; RETURN NO ACTION
20$:	MOV	BF.ADD(R3),R0	; current address
	SUB	BF.CAD(R3),R0	; minus cuurrent buffer address
	SUB	#BFLNK,R0	; minus header offset=bytes this buff.
	SUB	R0,BF.FUL(R3)	; now set index to start of buffer
	MOV	BF.CAD(R3),R0	; CURRENT BUFFER
	SUB	BF.FUL(R3),R1	; go foreward?
	BHI	40$		; yes
	BEQ	60$		; already there
30$:	MOV	2(R0),R0	; GO BACK 1 BUFFER
	.IFDF	$DEBUG
	BNE	35$		; *** DEBUG
	CALL	HLTER
35$:
	.ENDC
	SUB	#BFSIZ,BF.FUL(R3)
	ADD	#BFSIZ,R1	; add on buffer size
	BCC	30$		; NOT THERE YET
	BR	60$		; FOUND CORRECT ONE
40$:	SUB	#BFSIZ,R1	; done yet
	BLOS	50$		; yes
	ADD	#BFSIZ,BF.FUL(R3)
	MOV	(R0),R0		; GO FOREWARD
	.IFDF	$DEBUG
	BNE	45$		; *** DEBUG
	CALL	HLTER		; *** DEBUG
45$:
	.ENDC
	BR	40$
50$:	ADD	#BFSIZ,R1	; ADJUST TO POSITIVE
60$:	TSTNE	R1,70$		; index non zero?
	TSTEQ	2(R0),70$	; no backward link?
	MOV	2(R0),R0	; go back
	SUB	#BFSIZ,BF.FUL(R3) ; move index back
	ADD	#BFSIZ,R1	; to point to last byte
70$:	MOV	R0,BF.CAD(R3)	; SAVE CURRENT BUFFER
	ADD	R1,R0		; ALMOST CURRENT DAT
	ADD	#BFLNK,R0	; DATA -1
	MOV	R0,BF.ADD(R3)	; SAVED
	ADD	R1,BF.FUL(R3)	; CURRENT INDEX
	MOV	BF.MAX(R3),BF.CNT(R3) ; MAX
	SUB	BF.FUL(R3),BF.CNT(R3) ; - CURRENT = COUNT?
	MOV	#BFSIZ,R0	; BUFFER SIZE
	SUB	R1,R0		; - OFFSET = COUNT
	CMP	R0,BF.CNT(R3)	; WHICH ONE?
	BGT	80$		; PICK SMALLER
	MOV	R0,BF.CNT(R3)	; SMALLER ONE
80$:
	.IFDF	$DEBUG
	CALL	TEST		; *** DEBUG
	.ENDC
	CLC			; Success !!
	RETURN
;
;	GET TEMPORARY BUFFER
;
;		R2= current buffer
;		R3= temporary buffer address
;
GETTBF::MOV	#TMPBF,R3	; Temporary buffer address
SAVTBF::MOV	R3,-(SP)	; Save R3
	MOV	R2,R0		; Will be input
	MOV	#<BF.VSP>/2,R1	; Number of words
10$:	MOV	(R0)+,(R3)+	; transfer
	SOB	R1,10$		; Till done
	MOV	(SP)+,R3	; Restore buffer address
	RETURN
;
;	CALL	TMPIN
;	Set up input from temporary buffer
;		R2	= String address
;			= Last byte address in string+1
;		R0,R1	are destroyed
;	CALL	TMPINB
;		R2	= Buffer header
;
;
TMPINB::MOV	#-1,R1		; Indicate buffer header
	BR	TMPIN1
TMPIN::	CLR	R1		; Indicates R2=string
TMPIN1:	MOVB	SUBSTK,R0	; Get stack pointer
	CMPB	SUBSTK,SUBSTK+1	; Check on size
	BGE	40$		; Too big
	MOV	R3,-(SP)	; Save R3
	MOV	R1,-(SP)	; Save R1
	MOV	R2,-(SP)	; Save R2
	ADD	#2,R0		; Add 2
	MOVB	R0,SUBSTK	; New stack
	MOV	BUFADD(R0),R3	; Get buffer header
	MOV	R3,BUFAD
	MOV	#SUBF0,R2	; Current end of buffer
	CALL	SAVTBF		; Make current same
	CALL	ENDBF		; go to end of buffer
	CLR	R1		; Deposit 0
	CALL	PWRD		; Chock buffer
	MOV	BF.FUL(R3),BF.SPC(R3)	; For traceback
	MOV	(SP)+,R2	; Restore
	TSTEQ	(SP)+,10$	; String input ??
5$:	CALL	GBYT2		; Get byte
	BLOS	20$		; Done ?
	CALL	PBYT		; Save it
	BR	5$		; Continue till done
10$:	MOVB	(R2)+,R1	; Get 1 byte
	BEQ	20$		; At end of buffer ?
	CALL	PBYT		; Save it
	BR	10$
20$:	MOVB	#LF,R1		; Put line feed
	CALL	PBYT		; Into buffer
	MOV	BF.SPC(R3),R1	; Back to start of line
	CALL	FNDBF		; Set for reading buffer
	MOV	BF.END(r3),SUBF0+BF.END	; Reset end of buffer
	MOV	(SP)+,R3	; Restore
	CLC
30$:	RETURN
40$:	SEC
	RETURN
;
;	This checks the values of various parameters
;
	.IFDF	$DEBUG
TEST:	CMP	(R3),#BFSIZ	; too big?
	BHI	10$		; yes
	TST	BF.FUL(R3)	; too big?
	BLT	10$
	TSTNE	@BF.END(R3),10$	; Last not the end ?
	TSTEQ	BF.MAX(R3),1$	; Not input ?
	CMP	BF.FUL(R3),BF.MAX(R3)
	BHI	10$		; Not correct ?
1$:	MOV	BF.CAD(R3),-(SP)
	ADD	#BFLNK,(SP)
	CMP	(SP),BF.ADD(R3)	; current address too small?
	BHI	10$		; yes
	ADD	#BFSIZ,(SP)
	SUB	BF.CNT(R3),(SP)
	CMP	(SP),BF.ADD(R3)	; current address too big?
	BLO	10$
	TST	(SP)+
	return
10$:	JMP	HLTER
	.ENDC
;
; The input file is the exception to the buffer access rules.
; Since it is never extended it may be accessed directly.
;

BFLNK==3				; Offset from buffer to data-1
;
;	Macro to create buffer header with data area (sub-buffer)
;
	.psect	TABL,RO,D,LCL
;
;	Input buffer stack table
;
BUFADD::.WORD	IBUF1		; POINTS TO CURRENT INPUT HEADER
	.WORD	SUBF1,SUBF2,SUBF3,SUBF4,SUBF5,SUBF6 ; subst. buffers
	.PSECT	BUFFER,RW,GBL,D
	.MACRO	BUFF,SIZE
	.WORD	SIZE		; BF.CNT
	.WORD	0		; BF.FUL
	.WORD	10$+BFLNK	; BF.ADD
	.WORD	10$		; BF.CAD
	.WORD	10$		; BF.BEG
	.WORD	10$		; BF.END
	.BLKW	4		; BF.MAX,SPC,HED,VSP
10$:	.BLKW	2		; buffer foreward/backward links
	.BLKB	SIZE		; data area
	.ENDM
;
;	extra header macro (no data area)
;
	.MACRO	BUFFHD,ADD
	.WORD	0		; BF.CNT
	.WORD	0		; BF.FUL
	.WORD	ADD+BFLNK	; BF.ADD
	.WORD	ADD		; BF.CAD
	.WORD	ADD		; BF.BEG
	.WORD	ADD		; BF.END
	.BLKW	4		; BF.MAX,SPC,HED,VSP
	.ENDM
;
;	BUFFER DEFINITIONS
;		Each buffer consists of a header and a string of
;	sub-buffers each of uniform size.  While a buffer is being filled
;	sub-buffers are automatically added as needed from the pool.
;	If FNDBF or BEGBF are called then BF.MAX is generated and this
;	serves as a limit on adding more data, or reading past BF.MAX.
;	CLRBF and ENDBF reset BF.MAX so more data may be added.
;	Each sub-buffer consists of a Foreward link, backward link,
;	and data area.
;
BF.CNT==0			; Count of char remaining in sub-buffer
BF.FUL==2			; How many char total in buffer(all sub-buf)
BF.ADD==4			; Current char address
BF.CAD==6			; Current sub-BUFFER address
BF.BEG==10			; First sub-BUFFER address
BF.END=12			; LAST sub-BUFFER address
BF.MAX==14			; MAX # characters (all sub-buffers)
BF.SPC==16			; Spacing chars (current line)
BF.HED==20			; Header (begins current line)
BF.VSP==22			; Vertical spacing (all lines)
;
;	THE ACTUAL DATA BUFFER HAS THE FOLLOWING FORMAT
;		WORD 1=	FOREWARD LINK
;		WORD 2= BACKWARD LINK
;		3 - N = N-4 BYTES OF DATA
;
;
;	TEXT BUFFER HEADER (PRECEEDS TEXT) TEXT TERMINATED BY A NULL
;		APPLIES TO FOOTNOTE + SECONDARY BUFFERS
;
; BYTE	0	LINE SKIP COUNT
;	1	FLAGS 1=CHANGE BAR
;	2	LEFT MARGIN SPACING
;	3	SPACES/EXPANDABLE SPACE
;	4	EXPANDABLE SPACES TO LEFT
;	5	LEFT/RIGHT INDICATOR
;

;
;	IMPURE DATA STORAGE FOR INPUT BUFFERS
;
SUBLEV==3
BUFAD::	.WORD	IBUF1		; Current buffer pointer
SUBSTK:: .BYTE	0,SUBLEV*2	; current substitute pointer,max
;
;	Input buffer (contains 1 line only)
;
IBUF1::	BUFF	IBFSZ+4
;
;	substitution buffer headers
;
SUBF0::	BUFFHD	SUBBUF
SUBF1:	BUFFHD	SUBBUF
SUBF2:	BUFFHD	SUBBUF
SUBF3:	BUFFHD	SUBBUF
SUBF4:	BUFFHD	SUBBUF
SUBF5:	BUFFHD	SUBBUF
SUBF6:	BUFFHD	SUBBUF
SUBBUF:	.BLKB	BFSIZ+4		; Data for substitutions buffers
;
;	dynamic memory control locations
;
XBOT::	.BLKW	1		; BEGINNING OF ALLOCATED INDEX AREA
XTOP::	.BLKW	1		; HIGHEST VIRTUAL ADDRESS IN PROGRAM
LNKHD::	.BLKW	1		; POOL BUFFERS HEADER
;
;	Footnote buffer
;
FOTBF::	BUFF	BFSIZ
;
;	Deferred text buffer
;
TXDBF::	BUFF	BFSIZ
;
;	IF command buffer
;
IFBF::	BUFF	BFSIZ
;
;	Index entry buffer
;
INXBF::	BUFF	BFSIZ
;
;	Command line input buffer/ message buffer/ general format buffer
;		This buffer may be used freely as scratch storage
;
TTLIN==BFSIZ
TTBF::	BUFF	0		; Input buffer header
TTBUF::	.BLKB	BFSIZ+2		; COMMAND LINE INPUT BUFFER (82 bytes or more)
;
;	Final output buffer 
;
	.ifndf	RT11
	.WORD	0
HFOUT::	.WORD	OBFSZ,0,0				
OUBUF::	.BLKB	OBFSZ
	.endc
;
;	Escape sequence table
;
ESCBF::	BUFF	BFSIZ
;
;	Secondary text buffer
;
TX2BF::	BUFF	BFSIZ
;
;	Temporary buffers just a header/ no buffer
;
TMPBF::	BUFFHD	0
;
;	Title buffers
;
TTLBF::	BUFF	BFSIZ
;
;	Subtitle buffer
;
STLBF::	BUFF	BFSIZ
;
;	Backspace buffer
;		This buffer contains a line with spaces and underline chars.
;	for underlining if not doing it by backspace.
;
ULNMAX:: .WORD	0		; MAX NUMBER OF CHARS IN BUFFER
UBUFF::	.BLKB	ULNSZ+2
;
;	Traceback buffer
;		Format:
;		Address of current line number, followed by string
;		1 word line number
;		String-file-name
;		1 zero byte
;		Line number + string occupies <TRCLN> bytes
;
	.IF DF RT11
TRCBUF::.BLKW	1		; CURRENT BUFFER ADDRESS
	.BLKW	1		; LINE NUMBER
	.ASCIZ	"Main File"	; FILE NAME
	.BYTE	TRCLN-12.	; COMPLETE FIRST BUFFER
	.BLKB	6*TRCLN		; UP TO 6 NESTED .REQ FILES
	.IFF
TRCBUF::.BLKB	5*TRCLN+2
	.ENDC
	.END
	.TITLE RNFIO
	.IDENT	/BL1.0/
	.end
