	.TITLE	CC001		;Rsx version
	.ident	/X01.25/
 
	.NLIST	BEX
	.ENABL	LC, GBL
	.LIST	MEB
 
;
; C COMPILER
; PREPROCESSOR
;
; VERSION X01
;
; DAVID G. CONROY	17-JAN-78
;
; EDIT HISTORY
; 01  7-May-79 MM	Defined library as C: instead of LB:[1,1]
; 02 25-May-79 MM	Added Ifdef/Ifndf/else/endif processing
; 03 29-May-79 MM	Added undef processing
; 04 31-Jul-79 MM	Added RT11 support
; 05 24-Sep-79 MM	Fixed a stupid bug in RT11 #include processing
; 06 11-Jan-80 MM	Pre-insert some definitions
; 07 18-Mar-80 MM	Added #line, fixed another RT11 bug
; 08 07-May-80 MM	Added #ifndef as an alternative to #ifndf
; 09 02-Jun-80 MM	Fixed bug with pre-insertion
; 10 26-Feb-81 MM	Added #define _DATE "foo"
; 11 10-Jul-81 JSL	Allow #defines to have '$'
; 12 11-Feb-82 MM	Floating point lives.
; 13 23-Mar-82 MM	#define L xx ... long foo = 012L shouldn't expand.
; 14 02-Apr-82 MM	Comments aren't nested anymore.  Also, non terminated
;			strings within #ifdef blocks are error'ed out.
; 15 15-Apr-82 MM	Added c_rsts and c_vms
; 16 20-Apr-82 MM	Fixed error message for ;14
; 17 06-May-82 MM	Bug in dodef, for #define _DATE "foo"
; 18 25-May-82 MM	Better error message for ;16
; 19 25-Nov-82 MM	Added support for #if, larger buffer size.
; 20 27-Dec-82 MM	Globalized OKSID and OKID for CC002
;			Make initial definitions non-zero
; 21 02-Jun-84 MM	Added test for PRO-350
; 22 01-Aug-84 MM	Allow #<number> as synonym for #line <number>
; 23 21-Nov-84 MM	Don't eval #if if already false
; 24 06-Mar-85 CWRU/MM	Add PRO-350 specific code:
;			#define c_pos if compiler running on p/os
;			set flag so cc foo -a works on p/os
; 25 18-Mar-85 MM	Supress register dump on some fatal errors
;
; The following definitions are pre-inserted:
;
; _DATE		Compilation date as a quoted string
; decus		The Decus (Conroy) compiler
; nofpu		No floating-point support (for now) -- removed		;12
; nomacarg	No macros with arguments (for now)
; pdp11		Runs on a PDP-11 (or in compatibility mode)
; rsts		If the rsts compiler - set by -r
; rsx		If the rsx-11 compiler
; rt11		If the rt-11 compiler
; c_rsts	If the compiler is running on rsts
; c_vms		If the compiler is running on vms
; c_pos		If the compiler is running on p/os			;24
;

	.GLOBL	CCPREP
	.GLOBL	IFFAIL		;ERROR ROUTINE FOR EVALUATOR	;19
	.GLOBL	SPNOR		;SKIP WHITESPACE		;19
	.GLOBL	OKSID		;TEST "START OF ID"		;20
	.GLOBL	OKID		;TEST "IN ID"			;20
.IF NE	RSX							;04
	.MCALL	CALL
	.MCALL	CALLR
	.MCALL	RETURN
 
	.MCALL	GET$S
	.MCALL	PUT$S
	.MCALL	CSI$
	.MCALL	CSI$1
	.MCALL	CSI$2
	.MCALL	OFNB$R
	.MCALL	CLOSE$
 
	CSI$
.IFF								;04 +

.MACRO	CALL	ARG1,ARG2
.IF B	ARG2
	  JSR	PC,ARG1
.IFF
	  JSR	ARG1,ARG2
.ENDC
.ENDM	CALL

.MACRO	CALLR	ARG1
	  JMP	ARG1
.ENDM

.MACRO	RETURN	ARG1
.IF B	ARG1
	  RTS	PC
.IFF
	  RTS	ARG1
.ENDC
.ENDM	RETURN

	.MCALL	.CSISPC, .FETCH, .LOOKUP, .CLOSE
.ENDC								;04 -

;
; EQUIVALENCES
; DEFINE MACRO BLOCK
;
 
LINK	=	0		;LINK TO NEXT MACRO
REPLEN	=	2		;SIZE OF TEXT
NAME	=	4		;START OF 8 BYTE NAME
BODY	=	NAME+8.		;START OF BODY
 
BLANK	=	40		;ASCII BLANK
TAB	=	11		;ASCII TAB
 
;
; LOCAL DATA
;
	.PSECT	LD001,OVR,GBL					;04
INCOM:	.WORD	0		;IN A COMMENT COUNT
INCOS:	.WORD	0		;IN A CHAR CONSTANT OR STRING
LINE:	.WORD	0		;LINE NUMBER
DEFS:	.WORD	0		;HEAD OF MACRO TABLE
FILE:	.WORD	P0IN		;POINTER TO SOURCE FDB
BEND:	.BLKW	1		;POINTER TO RECORD END
DELIM:	.BLKW	1		;DELIMITER FOR INCOS
STLINE:	.BLKW	1		;SAVE FOR LINE NUMBER WHILE INCLUDING
FLSLVL:	.WORD	0		;IF FALSE COUNTER		;02
TRULVL:	.WORD	0		;IF TRUE  COUNTER		;02
CMDFLG:	.BLKW	1		;COMMAND PROCESSING TEMP	;02
SPSAVE:	.BLKW	1		;SAVES STACK FOR #IF EVALUATOR	;19
EVERR:	.BLKW	1		;SET NON-ZERO IF EVALUATOR DIES	;19
.if ne	rsx
;
; RSX11-M specific globals and macro definitions
;

	.mcall	GTSK$S
;
ISRSTS	=	4		; Returned by GTSK$ for RSTS
ISVMS	=	5		; Returned by GTSK$ for VMS
ISMPLUS	=	6		; Returned by GTSK$ for RSX-11M+
ISPOS	=	11		; Returned by GTSK$ for P/OS (Professional)

tskbuf:	.blkw	16.		; Task parameter buffer
.iff
;
; RT11 specific macros and equivalences
;
	.mcall	.gval
;
; Define RT11 file stuff
; Note: the format of the file data block was defined in CC0RT.
;
INCCSI:	.BLKW	39.		;CSI COMMAND BLOCK FOR FILE NAME
INCBLK	=	INCCSI+<3*5*2>	;WHERE DEVBLK IS IN INCCSI
	.WORD	INCBLK		;DEFINE FDB
P0TMP:	.WORD	INC$CH		;ON CHANNEL (NUMBER DEFINED IN CC0RT)
	.WORD	0
	.WORD	0
	.WORD	0
	.BLKB	512.
.ENDC								;04 -

.IIF NDF SIZ.IB	SIZ.IB	=	300.				;19

IDBUF:	.BLKB	8.		;ID BUFFER
TBUF:	.BLKB	SIZ.IB+30.	;TEMP. BUFFER			;19
	.BLKB	2		;GUARD AREA BEFORE BUF FOR #line	;22
BUF:	.BLKB	SIZ.IB		;RECORD BUFFER			;19
 
	.PSECT	ER001
DEF:	.BYTE	144,145,146,151	;DEFINE IN LOWER CASE		;02 +
	.BYTE	156,145,000,000	;
INC:	.BYTE	151,156,143,154	;INCLUDE IN LOWER CASE
	.BYTE	165,144,145,000	;
IFD:	.BYTE	151,146,144,145	;IFDEF IN LOWER CASE
	.BYTE	146,000,000,000	;
IFNDF:	.BYTE	151,146,156,144	;IFNDF IN LOWER CASE		;08 +
	.BYTE	146,000,000,000	;
IFNDEF:	.BYTE	151,146,156,144	;IFNDEF IN LOWER CASE
	.BYTE	145,146,000,000	;				;08 -
IF:	.BYTE	151,146,000,000	;IF IN LOWER CASE		;19
	.BYTE	000,000,000,000	;				;19
IFEND:	.BYTE	145,156,144,151	;ENDIF IN LOWER CASE
	.BYTE	146,000,000,000	;
IFELSE:	.BYTE	145,154,163,145	;ELSE IN LOWER CASE
	.BYTE	000,000,000,000	;
UND:	.BYTE	165,156,144,145	;UNDEF IN LOWER CASE
	.BYTE	146,000,000,000	;				;02 -
LIN:	.BYTE	154,151,156,145	;LINE IN LOWER CASE		;07
	.BYTE	000,000,000,000	;				;07

BLN:	.ASCII	" "		;FOR OUTPUT OF A BLANK LINE

SYSINC::			;GLOBALIZE DIRECTORY NAME	;01
	.ASCIZ	"C:"		;SYSTEM INCLUDE DIRECTORY	;01
	.ASCIZ	"          "	;GET SPACE FOR TKB PATCHES	;01

PREDEF:	.ASCIZ	"decus 1"	;THESE ARE #DEFINED AT STARTUP	;06+/20+
	.ASCIZ	"pdp11 1"
	.ASCIZ	"nomacarg 1"
.IF EQ	RSX
	.ASCIZ	"rt11 1"
.IFF
	.ASCIZ	"rsx 1"
.ENDC
	.ASCIZ	""		;END OF DEFINITION LIST		;06-
PRRSTS:	.ASCIZ	"c_rsts 1"	;If the compiler is running	;15
PRVMS:	.ASCIZ	"c_vms 1"	;emulated			;15
PRPOS:	.ASCIZ	"c_pos 1"	;if running on p/os		;24
IFRSTS:	.ASCIZ	"rsts 1"	;-r switch			;15/20-
ERR01:	.ASCIZ	"I/O error on input"
ERR02:	.ASCIZ	"I/O error on output"
ERR03:	.ASCIZ	"Line overflow"
ERR04:	.ASCIZ	"Nested includes not permitted"
ERR05:	.ASCIZ	"Illegal control line"
ERR06:	.ASCIZ	"Cannot open include file"
ERR07:	.ASCIZ	"Illegal comment in define"
ERR08:	.ASCIZ	"Too few #ifdef - else found"
ERR09:	.ASCIZ	"Too few #ifdef - endif found"
ERR10:	.ASCIZ	"#undef object undefined"
ERR11:	.ASCIZ	"Inside #ifdef block at end.  Depth = "
ERR12:	.ASCIZ	"Non-terminated string or character constant."	;16/18
ERR13:	.ASCIZ	/#if parse stopped at "/			;19
ERR14:	.ASCIZ	/<end of line>/
	.EVEN
 

;+
; ** $MAIN - PREPROCESSOR MAINLINE
;
; THIS IS THE MAIN LOOP OF THE PREPROCESSOR. IT IS CALLED FROM CC000
; WITH A TEMP FILE OPEN (FOR WRITING) ON P0OUT, AND THE ORIGINAL USER
; SOURCE OPEN FOR READING ON P0IN (P0IN WILL EVENTUALLY BE REUSED AS
; THE ASM OUTPUT FDB, WHERE IT WILL BE CALLED P2OUT).
;
; THIS ROUTINE READS THE SOURCE, PERFORMING THE REQUIRED DEFINES AND
; INCLUDES, AND WRITING THE WHOLE LOT TO THE TEMP FILE.
;-
 
;DEBUG+
;IN...:	.ASCII	"Input  :"
;	.BYTE	200
;OUT...:	.ASCII	"Output :"
;	.BYTE	200
;	.EVEN
;DEBUG-

	.PSECT	CC001						;04
;
; LOAD PREDEFINED STUFF						;06+
;

CC001::								;04
CCPREP:
	MOV	#DATDEF,R1	;#define _DATE			;10+;11;15
	CALL	DODEF		;DO IT				;15
	MOV	#PREDEF,R1	;START OF PREDEFINED BUFFER
10$:	TSTB	(R1)		;AT THE END?
	BEQ	20$		;YES, START THE REAL STUFF
	CALL	DODEF		;DEFINE IT			;15
	BR	10$		;GET ANOTHER
20$:
;								;15+
; Define rsts if -r switch, then c_rsts or c_vms
;
	TSTB	RFLAG		;-R REQUESTED
	BEQ	30$		;NO, CONTINUE
	MOV	#IFRSTS,R1	;YES, DO IT
	CALL	DODEF
30$:
.if ne	rsx							;15+
;
; Do a get task to get the task name and default UIC
;
	GTSK$S	#tskbuf		;Get task parameters
	mov	tskbuf+G.TSSY,#ISRSTS	;Op. system unique code
	bne	40$		;Not today
	mov	#prrsts,r1	;yep
	call	dodef
40$:				;
	cmp	tskbuf+G.TSSY,#ISVMS	;VMS?
	bne	50$		;No
	mov	#prvms,r1	;Yep
	call	dodef
50$:
	cmp	tskbuf+G.TSSY,#ISPOS	;PRO-350			;21+
	bne	55$			;No
	incb	$$pos			;Set POS flag
	mov	#prpos,r1		;do a definition		;24
	call	dodef			;				;24
55$:
.iff
;
; RT11 specific code:  set lower-case bit, check if it's really RSTS/E
; emulation.  Then do an incredable hack on RSTS to find the command line.
;
	cmp	-(sp),-(sp)	; Get temp for .gtval
	mov	sp,r1		; R1 -> .gtval pmtr. block
;
; Note: someday, we may have to test for RT11 emulation on vms, too.
;
	.gval	r1,#0		; Get first word of RMON
	cmp	(sp)+,(sp)+	; Clean the stack
	tst	r0		; It's non-zero on native RT11
	bne	40$		; Br if native
	mov	#prrsts,r1	; do it
	call	dodef		;
40$:
.endc								;15-

	CLR	LINE		;NO LINES READ YET		;06 -
	CALL	SHARP		;OUTPUT A # 0 TO FIX PASS 1	;09

PRLOOP:	MOV	#SIZ.IB,-(SP)	;PUSH MAXIMUM LINE LENGTH	;04+;19
	MOV	#BUF,-(SP)	;AND BUFFER START
	MOV	FILE,R0		;R0 -> CURRENT INPUT FILE
	CALL	RDLINE		;GO GET A LINE
	BIT	(SP)+,(SP)+	;CLEAR STACK, LEAVE C-BIT ALONE	;04 -
	BCS	30$		;ERROR, MIGHT BE EOF
	INC	LINE		;UPDATE LINE NUMBER
	MOV	#BUF,BEND	;COMPUTE THE ADDRESS OF THE
	ADD	R0,BEND		;END OF THE RECORD		;04
	CLRB	@BEND		;MARK BYTE PAST END FOR EVAL	;19
;DEBUG+
;	.MCALL	.PRINT
;	.PRINT	#IN...
;	.PRINT	#BUF
;DEBUG-
	CMPB	BUF,#'#		;IS IT A CONTROL LINE
	BNE	20$		;NO
	TST	INCOS		;IN CHAR. CONSTANT OR STRING
	BNE	20$		;IF SO, NOT A CONTROL LINE
	TST	INCOM		;IN A COMMENT
	BNE	20$		;IF SO, NOT A CONTROL LINE
	CALL	CONTRL		;PROCESS CONTROL LINE
	BR	PRLOOP		;AND GO FOR MORE
 
20$:	TST	FLSLVL		;ACTUALLY COMPILING?		;02 +
	BEQ	25$		;YES
	CALL	PUTBLN		;NO, OUTPUT A BLANK LINE
	BR	PRLOOP		;AND DO ANOTHER			;02 -

25$:	CALL	EXPAND		;EXPAND ANY MACROS
;DEBUG+
;	CLRB	@BEND
;	.PRINT	#OUT...
;	.PRINT	#BUF
;DEBUG-
	MOV	BEND,R1		;COMPUTE RECORD
	SUB	#BUF,R1		;SIZE
	MOV	R1,-(SP)	;PUSH NUMBER OF BYTES TO OUTPUT	;04 +
	MOV	#BUF,-(SP)	;PUSH BUFFER ADDRESS
	MOV	#P0OUT,R0	;GET FILE DATA BLOCK
	CALL	PUTTXT		;WRITE IT OUT
	BIT	(SP)+,(SP)+	;CLEAR STACK, LEAVE C-BIT ALONE	;04 -
	BCC	PRLOOP		;AND GO FOR MORE
	MOV	#ERR01,R0	;I/O ERROR ON OUTPUT
	JMP	CCFAIL		;DIE				;25
 
30$:
	TST	R0		;IS THE ERROR "END OF FILE"	;04
	BEQ	40$		;YES
	MOV	#ERR02,R0	;I/O ERROR ON INPUT
	JMP	CCFAIL		;DIE				;25
 
40$:	CMP	FILE,#P0IN	;IS THE FILE STANDARD INPUT
	BEQ	50$		;YES
.IF NE	RSX							;04
	CLOSE$	FILE		;NO, CLOSE THE INCLUDE FILE
.IFF								;04
	.CLOSE	#INC$CH		;AND CLOSE THE FILE		;04
.ENDC								;04
	MOV	#P0IN,FILE	;SET FILE TO STANDARD INPUT
	MOV	STLINE,LINE	;BACK UP LINE NUMBER
	CALL	SHARP		;OUTPUT A SHARP RECORD AND
	BR	PRLOOP		;GO BACK FOR MORE
 
50$:	MOV	TRULVL,R2	;CHECK IF DEPTH			;02 +
	ADD	FLSLVL,R2	;BOTH SHOULD BE ZERO
	BEQ	70$		;NO PROBLEMS
	MOV	#TBUF,R1	;TROUBLE, GET TEMP BUFFER
	MOV	LINE,R0		;PRINT LINE NUMBER
	CALL	$ITOC
	MOVB	#'#,(R1)+	;WITH SOME COMMENTARY
	MOVB	#' ,(R1)+	;AND A SPACE
	MOV	#ERR11,R0	;AND AN ERROR MESSAGE
60$:	MOVB	(R0)+,(R1)+	;ALL THE BYTES,
	BNE	60$		;PLEASE.
	DEC	R1		;Back up over the trailing null	;14
	MOV	R2,R0		;RECOVER DEPTH
	CALL	$ITOC		;INTO THE BUFFER
	CLRB	(R1)+		;TERMINATOR
	MOV	#TBUF,R0	;GET ERROR LINE AND
	CALL	CCERR		;PRINT THE ERROR MESSAGE
	INC	NERRS		;IT'S A PROBLEM			;02 -
;
70$:	MOV	#P0OUT,R0	;CLEAN UP THE LAST BUFFER	;04
	CALLR	FLUSH		;SO RT11 READS OK		;04
				;FLUSH RETURNS TO MAINLINE	;04
 
;+								;15+
; ** DODEF
;
; DEFINE A STRING
;
; INPUT:
;	R1 -> ASCIZ STRING (foo)
;
; OUTPUT:
;	R1 -> BYTE FOLLOWING NULL TRAILER OF ARG. STRING
; Generates:
;	#define	foo
;
; USES	R0,R5, BUF, BEND, AND WHATEVER ELSE CONTRL USES
;-

DODEF:
	MOV	#BUF,R5		;POINT TO WORK BUFFER
	MOV	#DEF,R0		;POINT TO "DEFINE"
	MOVB	#'#,(R5)+	;CREATE A "#define " STRING
20$:	MOVB	(R0)+,(R5)+	;COPY IN DEFINE
	BNE	20$		;ALL OF IT
	MOVB	#' ,-1(R5)	;THEN A BLANK
30$:	MOVB	(R1)+,(R5)+	;NOW, MOVE IN THE WORD
	BNE	30$		;TO BE DEFINED
	DEC	R5		;DON'T INCLUDE TRAILING NULL ??		;17
	MOV	R5,BEND		;SAVE THE LENGTH
	MOV	R1,-(SP)	;SAVE THE PREDEFINED BUFFER PTR
	CALL	CONTRL		;DO A CONTROL LINE
	MOV	(SP)+,R1	;RECOVER PREDEFINED PTR
	RETURN			;AND EXIT				;15-

;DEBUG+
;DB001:	.ASCIZ	"Up true counter"
;DB002:	.ASCIZ	"Up false counter"
;DB003:	.ASCIZ	"Endif drops false counter"
;	.EVEN
;DEBUG-

;+
; ** CONTRL - PROCESS CONTROL LINES
;
; THIS ROUTINE IS CALLED WHENEVER A CONTROL LINE IS ENCOUNTERED IN THE
; INPUT.
;
; INPUTS:
;	BUF=THE RECORD
;      BEND=POINTER TO THE END OF THE RECORD
;-
 
CONTRL:
	MOV	#BUF+1,R5	;POINT JUST PAST THE '#'
	CALL	SPNOR		;SKIP BLANKS
	BCS	920$ ;4$	;IGNORE BLANK LINES		;02/22
	CLR	CMDFLG		;INITIALIZE COMMAND TEST	;02
	CMPB	R0,#'0		;IF THE LINE			;22+
	BLO	900$		;STARTS WITH A
	CMPB	R0,#'9		;DIGIT, IT'S A SYNONYM
	BHI	900$		;FOR #line
	JMP	910$		;SO GO DO IT.
900$:				;				;22-
	CALL	GETID		;GET TYPE
 
	MOV	#IFD,R0		;TEST FOR			;02 +
	CALL	EQUAL		;IFDEF
	BCC	140$		;GO FOR IT

	MOV	#IFNDF,R0	;TEST FOR
	CALL	EQUAL		;IFNDF
	BCC	132$		;YES, GO FOR IT			;08 +
	MOV	#IFNDEF,R0	;NO, TEST FOR
	CALL	EQUAL		;IFNDEF				;08 -
	BCC	132$		;GO FOR IT			;19+
	MOV	#IF,R0		;NO, TEST FOR
	CALL	EQUAL		;IF
	BCS	1$		;NO, TRY NEXT
	TST	FLSLVL		;#IF, ALREADY FALSE?		;23
	BNE	154$		;DON'T EVALUATE IF SO.		;23
	CLR	EVERR		;EVAULATE #IF EXPRESSION, CLEAR ERROR
	MOV	R5,-(SP)	;SAVE POSITION IN INPUT LINE
	CALL	EXPND1		;AND EXPAND ANY MACRO'S
	MOV	(SP)+,R5	;RESET POSITION IN LINE
	TST	EVERR		;PROBLEM IN EXPANSION?
	BNE	210$		;YES, JUMP OUT.
	MOV	SP,SPSAVE	;SAVE STACK FOR ERROR EXIT FROM EVAL
	CALL	IFEVAL		;AND EVALUATE #IF EXPRESSION
	TST	EVERR		;PROBLEM?
	BEQ	220$		;NO, NORMAL EXIT.
210$:	JMP	130$		;YES, TAKE ERROR EXIT.
220$:	TST	R2		;RESULT FROM EVAL, 0 == FALSE, 1 == TRUE
	BNE	141$		;TRUE
	BR	154$		;FALSE				;19-

132$:	INC	CMDFLG		;IFNDF SEEN, WANT C-BIT SET FROM LOOKUP
;
; #Ifdef/ifndf processing
;
140$:	TST	FLSLVL		;COMPILE IT?
	BNE	154$		;BRANCH IF NOT
	CALL	SPNOR		;SKIP OVER WHITE SPACE
	BCS	158$		;TROUBLE IF NONE
	CALL	OKSID		;MUST BE A
	BCS	158$		;LEGAL ID
	CALL	GETID		;GET THE IDENTIFIER
	CALL	LOOKUP		;LOOK FOR THE VARIABLE
	BIC	R0,R0		;GET RETURN (C-BIT) INTO R0
	ROL	R0		;R0 := 0 IF FOUND, 1 IF NOT FOUND
	CMP	CMDFLG,R0	;IF THEY'RE THE SAME, THE TEST SUCCEEDS
	BNE	154$		;BRANCH IF IF FAILS
141$:				;TRUE TEST (FROM #IF EVALUATOR)		;19
	INC	TRULVL		;INCREMENT TRUE COUNTER
;DEBUG+
;	.MCALL	.PRINT
;	.PRINT	#DB001
;DEBUG-
920$:	BR	4$		;AND GO TO EXIT				;22
154$:	INC	FLSLVL		;TURN OFF COMPILATION
;DEBUG+
;	.PRINT	#DB002
;DEBUG-
	BR	4$		;AND EXIT, PRINTING A BLANK LINE
158$:	JMP	100$		;TROUBLE EXIT

1$:	MOV	#IFELSE,R0	;TEST FOR
	CALL	EQUAL		;ELSE
	BCS	2$		;NO, TRY NEXT
;
; #else Processing
;
	TST	FLSLVL		;SKIPPING COMPILING?
	BEQ	164$		;IF SO, GO TRY TRUE COUNT
	DEC	FLSLVL		;YES, DROP FALSE COUNT
	BEQ	162$		;MAKE IT TRUE IF ZERO NOW
	INC	FLSLVL		;NO, KEEP IT FALSE
	BR	4$		;AND EXIT
162$:	INC	TRULVL		;KEEP "INSIDE IF BLOCK" COUNT
	BR	4$		;AND GO EXIT

164$:	TST	TRULVL		;FALSE WAS ZERO.  ARE WE INSIDE AN IF?
	BNE	166$		;YES, KEEP ON TRUCKING
	MOV	#ERR08,R0	;NO, TROUBLE
	JMP	120$		;EXIT WITH AN ERROR MESSAGE
166$:	INC	FLSLVL		;ELSE MAKES IT FALSE
	DEC	TRULVL		;THUS, IT CAN'T BE TRUE
	BR	4$		;AND EXIT

2$:	MOV	#IFEND,R0	;TEST FOR
	CALL	EQUAL		;ENDIF
	BCS	3$		;NO, TRY NEXT
;
; #endif Processing
;
	TST	FLSLVL		;INSIDE A NON-COMPILE BLOCK?
	BEQ	172$		;BRANCH IF NOT.
;DEBUG+
;	.PRINT	#DB003
;DEBUG-
	DEC	FLSLVL		;ONE LESS FALSEHOOD
	BR	4$		;GO TO COMMON EXIT
172$:	TST	TRULVL		;NOT FALSE, IS IT TRUE?
	BEQ	176$		;IF NOT, GO TO TROUBLE
	DEC	TRULVL		;DROP IF BLOCK COUNTER
	BR	4$		;GO TO COMMON EXIT
176$:	MOV	#ERR09,R0	;END WITHOUT MATCHING IF
	JMP	120$		;TAKE ERROR EXIT		;02 -



3$:	TST	FLSLVL		;COMPILING NOW?
	BEQ	5$		;BRANCH IF SO
4$:	JMP	65$		;PUT OUT A BLANK LINE		;03 +

5$:	MOV	#DEF,R0		;TEST FOR
	CALL	EQUAL		;DEFINE
	BCC	6$		;BR IF SO

	INC	CMDFLG		;MARK IT "UNDEFINED"
	MOV	#UND,R0		;TEST FOR
	CALL	EQUAL		;UNDEFINED
	BCC	6$		;BRANCH IF SO
	JMP	70$		;NO, TRY NEXT			;03 -

;
; #define/undef processing
;
 
6$:	CALL	SPNOR		;SKIP TO MACRO NAME
	BCS	66$		;NO NAME
	CALL	OKSID		;MUST BE A
	BCS	66$		;LEGAL ID
	CALL	GETID		;GET THE NAME AND
	CALL	LOOKUP		;LOOK IT UP
	BCC	8$		;GOT IT				;03 +
	TST	CMDFLG		;NOT THERE, DEFINING IT?
	BEQ	30$		;YES, DO SO
	JMP	130$		;CAN'T UNDEFINE NOTHING		;03-, 06
 
8$:	MOV	#DEFS,R1	;SEARCH FOR THE ITEM
10$:	CMP	(R1),R0		;THAT IS BEFORE THE ITEM IN
	BEQ	20$		;QUESTION
	MOV	(R1),R1		;FOLLOW LINKS
	BNE	10$		;IT
	CRASH			;MUST BE THERE
20$:	MOV	(R0),(R1)	;UNLINK THE ITEM IN QUESTION
	CALL	$FREE		;FREE IT
	TST	CMDFLG		;UNDEFINING?			;03
	BEQ	30$		;NO, DO DEFINE			;03
	JMP	65$		;YES, ALL DONE.			;03
 
30$:	CALL	SPNOR		;SKIP TO THE START
	BCS	32$		;OF THE MACRO AND
	DEC	R5		;POINT R5 AT IT
 
32$:	MOV	R5,R4		;SET UP TO
	MOV	R5,R3		;COMPRESS THE MACRO
	CLR	R2		;ZERO COMMENT DEPTH
 
34$:	CMP	R3,BEND		;BREAK LOOP IF
	BHIS	42$		;DONE
	MOVB	(R3)+,R0	;PICK UP SOURCE CHARACTER
	TST	R2		;ARE WE IN A COMMENT
	BEQ	38$		;NO
	CMP	R3,BEND		;IS THERE ANOTHER CHARACTER
	BHIS	34$		;NO
.if ne	0			;Comments aren't nested now		;14
	CMPB	R0,#'/		;CHECK IF
	BNE	36$		;ENTERING
	CMPB	(R3),#'*	;ANOTHER
	BNE	34$		;COMMENT AND
	INC	R2		;INCREASE DEPTH AND
	INC	R3		;SKIP THE '*' IF
	BR	34$		;YES
.endc									;14
36$:	CMPB	R0,#'*		;CHECK IF LEAVING
	BNE	34$		;A COMMENT
	CMPB	(R3),#'/	;AND
	BNE	34$		;DECREASE DEPTH
	DEC	R2		;AND
	INC	R3		;SKIP THE '/' IF
	BR	34$		;YES
 
38$:	CMPB	R0,#'/		;TEST IF
	BNE	40$		;ENTERING
	CMP	R3,BEND		;A
	BHIS	40$		;COMMENT
	CMPB	(R3),#'*	;AND
	BNE	40$		;INCREASE
	INC	R2		;DEPTH AND
	INC	R3		;SKIP OVER THE '/*' IF
	BR	34$		;YES
 
40$:	MOVB	R0,(R4)+	;SAVE BYTE INTO THE
	BR	34$		;COMPRESSED LINE
 
42$:	TST	R2		;DID THE COMPRESS END IN A COMMENT
	BEQ	44$		;NO
	MOV	#ERR07,R0	;YES
	CALL	ERROR0		;COMPLAIN
 
44$:	CMP	R4,R5		;DELETE TRAILING WHITE SPACE
	BLOS	46$		;FROM
	MOVB	-(R4),R0	;THE
	CMP	R0,#BLANK	;MACRO
	BEQ	44$		;BODY
	CMP	R0,#TAB		;TO
	BEQ	44$		;AVOID
	INC	R4		;LINE OVERFLOW
 
46$:	MOV	R4,BEND		;COMPUTE
	SUB	R5,R4		;LENGTH OF THE BODY
	MOV	R4,R0		;THEN GET
	ADD	#BODY,R0	;SPACE FOR THE
	CALL	$ALLOC		;MACRO BLOCK

	MOV	DEFS,(R0)	;LINK
	MOV	R0,DEFS		;INTO
	TST	(R0)+		;LIST
	MOV	R4,(R0)+	;REPLEN
	MOV	#IDBUF,R1	;COPY
50$:	MOVB	(R1)+,(R0)+	;IN
	CMP	R1,#IDBUF+8.	;THE
	BLO	50$		;NAME
60$:	CMP	R5,BEND		;COPY
	BHIS	65$		;IN
	MOVB	(R5)+,(R0)+	;THE
	BR	60$		;BODY
65$:	CALL	PUTBLN		;PUT OUT A BLANK LINE SO
	JMP	130$		;THE LINENUMBERS ARE CORRECT
 
66$:	JMP	100$		;ILLEGAL CONTROL LINE
 
70$:	MOV	#INC,R0		;TEST FOR
	CALL	EQUAL		;INCLUDE
	BCS	95$		;BR IF NOT

;
; #include processing
;
 
	CMP	FILE,#P0IN	;ARE WE IN AN INCLUDE
	BEQ	80$		;NO
	MOV	#ERR04,R0	;YES, GIVE
	BR	120$		;DIAGNOSTIC
 
80$:	CALL	SPNOR		;SKIP TO THE
	BCS	100$		;FILE NAME
	MOV	#TBUF,R1	;POINT AT TEMP NAME BUFFER
	MOV	#'",DELIM	;ASSUME ORDINARY INCLUDE
	CMP	R0,#'"		;IS IT
	BEQ	90$		;YES
	MOV	#'>,DELIM	;ASSUME SYSTEM INCLUDE
	CMP	R0,#'<		;IS IT
	BNE	100$		;NO
	MOV	#SYSINC,R2	;COPY IN "C:" (OR WHATEVER)	;01
82$:	MOVB	(R2)+,(R1)+	;
	BNE	82$		;
	DEC	R1		;BACK UP OVER THE NULL
90$:	CMP	R5,BEND		;NOW LOOK FOR THE
	BHIS	100$		;END OF THE NAME
	MOVB	(R5)+,R0	;GRAB CHARACTER FROM NAME
	CMP	R0,DELIM	;IS IT THE DELIMITER
	BEQ	92$		;YES
	CMPB	R0,#'a		;IS IT LOWER CASE
	BLO	91$		;NO
	CMPB	R0,#'z		;
	BHI	91$		;NO
	BICB	#' ,R0		;FORCE TO UPPER
91$:	MOVB	R0,(R1)+	;SAVE IN BUFFER AND
	BR	90$		;CONTINUE
92$:
.IF NE	RSX							;04
	SUB	#TBUF,R1	;COMPUTE FILE NAME LENGTH
	MOV	R1,CSI+C.CMLD	;SAVE IT
	MOV	#TBUF,CSI+C.CMLD+2 ;ALSO SAVE FILE NAME ADDRESS
	CSI$1	#CSI		;PARSE THE
	BCS	110$		;FILE
	CSI$2	,OUTPUT		;USING THE
	BCS	110$		;DREADED CSI
 
	MOV	#P0TMP,R0	;OPEN
	MOV	#P0TMP+F.FNB,R1	;THE
	MOV	#CSI+C.DSDS,R2	;HARD WAY
	MOV	#DFNB1,R3	;SO THAT
	CALL	.PARSE		;NO EXTRA
	BCS	110$		;STUFF
	OFNB$R			;GETS
	BCS	110$		;LOADED
.IFF								;04 +
	CLRB	(R1)		;TERMINATE THE STRING		;05
	.CSISPC	#INCCSI,#DEFEXT,#TBUF ;PARSE THE FILE NAME
	BCS	110$		;DIE ON ERROR
	MOV	(SP)+,R0	;ANY SWITCHES?
	BEQ	93$		;NO, GOOD FOR HIM
	ASL	R0		;YES, TRASH THE STACK
	ADD	R0,SP		;TO REMOVE SWITCH STUFF
	BR	110$		;AND DIE TWITCHING

93$:
; Note: The fetch is not taken so as not to disturb free memory.
; the moral of the story is that all #include devices must have
; their handlers' pre-loaded (or loaded by the open of the main files.
;	.FETCH	@#50,#INCBLK	;FETCH THE HANDLER
;	BCS	110$		;DIE IF CAN'T FETCH IT
	.LOOKUP	#INCCSI,#INC$CH,#INCBLK
	BCS	110$		;DIE IF IT WON'T OPEN
.IFTF								;04 -
	MOV	LINE,STLINE	;SAVE LINE NUMBER
	CLR	LINE		;RESET LINE NUMBER
	MOV	#P0TMP,FILE	;RESET FILE NAME		;04
.IFF								;04 +
	CLR	P0TMP+FDB$NF	;MAKE SURE THE FDB IS
	CLR	P0TMP+FDB$FP	;EMPTY IN PREPARATION FOR
	CLR	P0TMP+FDB$BL	;THE FIRST READ
.ENDC								;04 -
	CALL	SHARP		;OUPUT '#' RECORD
	BR	130$		;DONE
 
95$:	MOV	#LIN,R0		;IS IT LINE NUMBER?		;07 +
	CALL	EQUAL		;GO FOR IT
	BCS	100$		;BRANCH IF NOT

;
; #line processing
;

	CALL	SPNOR		;SKIP OVER WHITESPACE
	BCS	96$		;HACK EXIT IF EMPTY
910$:				;HERE FOR "#number"		;22
	DEC	R5		;R5 -> FIRST NON-WHITE CHAR.
	CMPB	R0,#'0		;#LINE 012
	BLO	96$		;NO
	CMPB	R0,#'9		;#LINE 999
	BLOS	97$		;YES
;
; Note that there is a guard area before "BUF"
; so this can't write randomly in memory.
;
96$:	MOVB	#' ,-(R5)	;FIX THE LINE
	MOVB	#'0,-(R5)	;SO PASS 1 ACCEPTS IT
;
97$:	MOVB	#'#,-(R5)	;PRECEEDED BY A SHARP
	MOV	BEND,-(SP)	;RECORD END POINTER
	SUB	R5,(SP)		;NOW IT'S RECORD LENGTH
	MOV	R5,-(SP)	;HERE'S THE RECORD
	MOV	#P0OUT,R0	;AND THE FILE
	CALL	PUTTXT		;GO FOR IT
	BIT	(SP)+,(SP)+	;CLEAR THE STACK
	BR	130$		;AND GO TO COMMON EXIT		;07-

100$:	MOV	#ERR05,R0	;ILLEGAL CONTROL LINE
	BR	120$		;
110$:	MOV	#ERR06,R0	;CONNOT OPEN FILE
120$:	CALL	ERROR0		;COMPLAIN
 
130$:	RETURN			;FINIS

;+								;19
; ** IFFAIL -- FAILURE EXIT FROM #IF EVAULATOR
;
; JUMP HERE TO ABORT FROM THE RECURSIVE DESCENT EVALUATOR PARSER.
;
; INPUTS:
;	R0=ERROR MESSAGE
IFFAIL:
	INC	EVERR		;SET ERROR CODE
	CALL	ERROR0		;PRINT ERROR MESSAGE.
	MOV	#ERR13,R0	;"Parse stopped at..."
	MOV	#TBUF,R1	;BUFFER
10$:	MOVB	(R0)+,(R1)+	;WRITE IT OUT
	BNE	10$		;ALL OF IT
	DEC	R1		;BACK UP OVER EOS.
	MOV	R5,R0		;NEXT BYTE TO SCAN
	CMP	R5,BEND		;WERE WE AT THE END ALREADY?
	BLO	20$		;NO, CONTINUE NORMALLY
	MOV	#ERR14,R0	;YES, PUT OUT A SPECIAL.
20$:	MOVB	(R0)+,(R1)+	;WRITE IT OUT
	BNE	20$		;TILL EOS
	MOVB	#'",(R1)+	;TERMINATE TEXT
	CLRB	(R1)		;TERMINATE STRING
	MOV	#TBUF,R0	;PRINT THIS BUFFER
	CALL	CCERR		;PRINT IT
	MOV	SPSAVE,SP	;RETURN TO EVAL CALLER
	RETURN			;UNWINDING THE STACK			;19-

;+
; ** EXPAND - EXPAND OUT MACROS
;
; THIS ROUTINE IS CALLED FOR ANY NON CONTROL LINES ENCOUNTERED IN THE
; INPUT. IT SEARCHES THE LINE FOR ANY IDENTIFIERS THAT HAVE BEEN  SET
; UP AS MACROS VIA A DEFINE CONTROL LINE, AND EXPANDS THEM.
;
; INPUTS:
;	BUF=THE RECORD (EXPAND)
;	 R5=THE RECORD (EXPND1)  (R5 USED)
;      BEND=POINTER TO THE END OF THE RECORD
;-
 
EXPAND:	MOV	#BUF,R5		;POINT AT THE START
EXPND1:				;HERE TO EVALUATE FROM MID-LINE	;19

10$:	CMP	R5,BEND		;BREAK LOOP IF
	BLO	12$		;ALL DONE
	TST	INCOS		;Still in a string?			;14+
	BEQ	11$		;No, continue
	CLR	INCOS		;Clear flag so errors don't cascade
	INC	EVERR		;Error for evaluator			;19
	MOV	#ERR12,R0	;In a string at end of line
	CALL	ERROR0		;Complain about it
11$:				;Br here if line ends with backslash	;14-
	JMP	170$		;DONE WITH THIS LINE
 
12$:	MOVB	(R5)+,R0	;GET CHARACTER FROM LINE
	TST	INCOS		;ARE WE IN CHAR CONST OR STRING
	BEQ	30$		;BR IF NOT
	CMPB	R0,DELIM	;LEAVING?
	BNE	20$		;NO
	DEC	INCOS		;LEAVE STRING OR CHAR CONST
	BR	10$		;MODE
 
20$:	CMPB	R0,#'\		;ESCAPE SEQUENCE?
	BNE	10$		;NO
	CMP	R5,BEND		;AT THE END
	BHIS	11$		;YES -- Don't check for "in a string"	;14
	INC	R5		;SKIP NEXT CHARACTER
	BR	10$		;

30$:	TST	INCOM		;IN A COMMENT
	BEQ	50$		;BR IF NOT
	CMP	R5,BEND		;SEE IF THERE IS ANOTHER CHAR.
	BHIS	10$		;NO
.if ne 0			; Comments don't nest now		;14
	CMPB	R0,#'/		;IS IT A '/*'
	BNE	40$		;NO
	CMPB	(R5),#'*	;MAYBE
	BNE	10$		;NO
	INC	INCOM		;INCREASE COMMENT DEPTH
	INC	R5		;SKIP THE '*'
	BR	10$		;AND GO AGAIN
.endc									;14
40$:	CMPB	R0,#'*		;IS IT A '*/'
	BNE	10$		;NO
	CMPB	(R5),#'/	;MAYBE
	BNE	10$		;NO
	DEC	INCOM		;DECREASE COMMENT DEPTH
	INC	R5		;SKIP THE '/'
	BR	10$		;AND GO AGAIN
 
50$:	CMPB	R0,#'"		;ENTERING A STRING
	BEQ	52$		;YES
	CMPB	R0,#''		;ENTERING A CHARACTER CONSTANT
	BNE	60$		;NO
52$:	MOV	R0,DELIM	;SAVE WHICH
	INC	INCOS		;SET IN STRING OR CHAR CONSTANT
	BR	10$		;GO AGAIN
 
60$:	CMPB	R0,#'/		;ENTERING A COMMENT
	BNE	70$		;NO
	CMP	R5,BEND		;PERHAPS
	BHIS	70$		;NO
	CMPB	(R5),#'*	;IS IT A '/*'
	BNE	70$		;NO
	INC	INCOM		;INCREASE COMMENT DEPTH
	INC	R5		;SKIP OVER THE '*'
	BR	10$		;GO AGAIN
 
70$:	CALL	OKSID		;COULD THIS CHAR. START AN ID
	BCS	75$		;NO					;13
	MOV	R5,-(SP)	;SAVE WHERE WE ARE
	CALL	GETID		;GET THE ID
	CALL	LOOKUP		;AND LOOK IT UP
	BCC	80$		;FOUND IT
	TST	(SP)+		;OH WELL
	BR	10$		;JUST CONTINUE

75$:	CALL	OKID		;BUT, IS IT A NUMERIC CONSTANT?		;13+
	BCS	10$		;NO, JUST CONTINUE
	CALL	GETID		;YES, SKIP OVER IT SO #define L xxx WORKS
	BR	10$		;BACK FOR MORE				;13-

80$:	DEC	(SP)		;POINT (SP) AT ID[0]
	MOV	R5,R4		;COMPUTE THE
	SUB	(SP),R4		;DELTA SIZE
	NEG	R4		;OF
	ADD	#2,R4		;THE NEW
	ADD	REPLEN(R0),R4	;LINE
	BEQ	140$		;SAME SIZE
	BGT	110$		;NEW LINE IS LONGER
 
	ADD	R5,R4		;NEW LINE IS SHORTER
90$:	CMP	R5,BEND		;SO SHIFT IT
	BHIS	100$		;LEFT
	MOVB	(R5)+,(R4)+	;TO
	BR	90$		;RIGHT
100$:	MOV	R4,BEND		;SET NEW END OF BUFFER
	CLRB	(R4)		;AND FORCE TERMINATOR FOR DEBUGGING	;19
	BR	140$		;GO COPY IN TEXT
 
110$:	ADD	BEND,R4		;NEW LINE IS LONGER
	CMP	R4,#BUF+SIZ.IB	;IS THE LINE TOO LONG			;19
	BLO	120$		;NO
	INC	EVERR		;SET FLAG FOR EVAULATOR			;19
	MOV	#ERR03,R0	;COMPLAIN
	CALL	ERROR0		;ABOUT IT
	TST	(SP)+		;JUST FORGET ABOUT
	BR	10$		;THIS ONE
 
120$:	MOV	BEND,R5		;SET UP TO SLIDE THE
	MOV	R4,BEND		;LINE RIGHT TO LEFT
	CLRB	(R4)		;FORCE TERMINATOR FOR DEBUG PRINTOUTS	;19
130$:	CMP	R5,(SP)		;SEE IF DONE
	BLOS	140$		;YES
	MOVB	-(R5),-(R4)	;SLIDE THE
	BR	130$		;LINE ALONG
 
140$:	MOV	(SP),R5		;COPY IN MACRO BODY
	MOVB	#' ,(R5)+	;BLANK
	MOV	REPLEN(R0),R4	;SIZE OF REPLACEMENT TEXT
	BEQ	160$		;NULL
	ADD	#BODY,R0	;R0 POINTS AT TEXT
150$:	MOVB	(R0)+,(R5)+	;COPY
	DEC	R4		;THE
	BNE	150$		;TEXT
160$:	MOVB	#' ,(R5)	;BLANK
	MOV	(SP)+,R5	;RESCAN THE TEXT
	JMP	10$		;GO AGAIN
 
170$:	RETURN			;FINIS


;+
; ** GETID - READ AN ID INTO IDBUF
;
; INPUTS:
;	R0=FIRST CHARACTER OF THE ID
;	R5=POINTER INTO THE BUFFER
;
; USES:
;	R1
;-
 
GETID:	MOV	#IDBUF,R1	;POINT AT ID BUFFER
 
10$:	CMP	R1,#IDBUF+8.	;WILL IT FIT
	BHIS	20$		;NO
	MOVB	R0,(R1)+	;YES, STORE IT
 
20$:	CMP	R5,BEND		;IS THERE A CHARACTER TO GET
	BHIS	30$		;NO
	MOVB	(R5)+,R0	;YES, GET IT
	CALL	OKID		;IS IT OK IN AN ID
	BCC	10$		;YES
	DEC	R5		;PUT IT BACK
 
30$:	CMP	R1,#IDBUF+8.	;NOW PAD THE
	BHIS	40$		;ID
	CLRB	(R1)+		;WITH
	BR	30$		;NULLS
 
40$:	RETURN			;DONE
 

;+
; ** OKSID - TEST IF CHARACTER IS OK AT THE START OF AN ID
; ** OKID  - TEST IF CHARACTER IS OK IN AN ID
;
; INPUTS:
;	R0=CHARACTER
;
; OUTPUTS:
;	C=0 IF OK, C=1 IF NOT
;-
 
	.ENABL	LSB
 
OKID:	CMPB	R0,#'0		;TEST FOR NUMERICS
	BLO	OKSID		;TOO LOW, BUT CHECK FOR $	;11
	CMPB	R0,#'9
	BLOS	20$
 
OKSID:
	CMPB	R0,#'$		;DOLLAR SIGN?			;07
	BEQ	20$		;OK NOW				;07

	CMPB	R0,#101		;UPPER CASE ALPHABETICS
	BLO	10$
	CMPB	R0,#132
	BLOS	20$
 
	CMPB	R0,#'_		;UNDERBAR
	BEQ	20$
 
	CMPB	R0,#141		;LOWER CASES ALPHABETICS
	BLO	10$
	CMPB	R0,#172
	BLOS	20$
 
10$:	SEC			;NOT LEGAL
	BR	30$
20$:	CLC			;LEGAL
30$:	RETURN
 
	.DSABL	LSB
 

;+
; ** SPNOR - SKIP BLANKS
;
; INPUTS:
;	R5=POINTER TO NEXT CHARACTER IN BUFFER
;
; OUTPUTS:
;	C=0
;	R0=FIRST NONBLANK CHARACTER
;	R5=UPDATED -- POINTS TO CHARACTER AFTER FIRST NON-BLANK
;
;	C=1 IF THE LINE RAN OUT FIRST (R0 == EOS)
;	If the line runs out, R5 will point beyond BEND so the		;19
;	unget code in the #if parser can "always" unget.		;19
;-
 
SPNOR:	CMP	R5,BEND		;TEST FOR LINE RUNOUT
	BHIS	10$		;
	MOVB	(R5)+,R0	;GET CHARACTER
	CMPB	R0,#BLANK	;SKIP
	BEQ	SPNOR		;BLANKS
	CMPB	R0,#TAB		;AND
	BEQ	SPNOR		;TABS
	CLC			;GOOD RETURN
	BR	20$		;
 
10$:	MOV	BEND,R5		;RESET R5 TO ALLOW RECALLS.	;19+
	INC	R5		;EVEN AFTER AN UNGET
	CLR	R0		;RETURN CONSISTANT VALUE	;19-
	SEC			;LINE RAN OUT
20$:	RETURN			;FINIS
 

;+
; ** LOOKUP - LOOKUP MACRO
;
; INPUTS:
;    IDBUF=THE NAME
;
; OUTPUTS:
;	R0=POINTER TO MACRO BLOCK
;
; USES:
;	R1, R2
;-
 
LOOKUP:	MOV	DEFS,R0		;GET HEAD OF THE MACRO TABLE
	BEQ	40$		;NULL
 
10$:	MOV	R0,R1		;R1=POINTER TO NAME
	ADD	#NAME,R1	;
	MOV	#IDBUF,R2	;R2=POINTER TO ID
 
20$:	CMPB	(R1)+,(R2)+	;SEE
	BNE	30$		;IF
	CMP	R2,#IDBUF+8.	;THE NAMES
	BLO	20$		;MATCH
	CLC			;FOUND IT
	BR	50$		;
 
30$:	MOV	(R0),R0		;CHAIN DOWN THE TABLE
	BNE	10$		;STILL MORE
40$:	SEC			;NOT FOUND
50$:	RETURN			;FINIS
 

;+
; ** ERROR0 - OUTPUT ERROR MESSAGES
;
; INPUTS:
;	R0=POINTER TO ASCIZ MESSAGE
;
; USES:
;	R0, R1
;-
 
ERROR0:	MOV	R0,-(SP)	;SAVE MESSAGE POINTER
 
	MOV	#TBUF,R1	;GET POINTER TO TEMP. BUFFER
	MOV	LINE,R0		;CONVERT
	CALL	$ITOC		;LINE NUMBER
	MOVB	#':,(R1)+	;FOR
	MOVB	#' ,(R1)+	;LOOKS
 
	MOV	FILE,R0		;GET FDB POINTER
	CMP	R0,#P0IN	;IF NOT
	BEQ	10$		;STANDARD INPUT
	CALL	$FDBTA		;PUT OUT FILE NAME
	MOVB	#':,(R1)+	;FOR
	MOVB	#' ,(R1)+	;LOOKS
 
10$:	MOV	(SP)+,R0	;GET MESSAGE POINTER
20$:	MOVB	(R0)+,(R1)+	;COPY
	BNE	20$		;THE MESSAGE TEXT
 
	MOV	#TBUF,R0	;THEN
	CALL	CCERR		;WRITE TO ERROR STREAM
	MOV	#BUF,R0		;WRITE THE NULL-TERMINATED LINE, TOO	;19
	CALL	CCERR		;
	INC	NERRS		;COUNT AN ERROR
	RETURN			;
 

;+
; ** SHARP - OUTPUT A LINE NUMBER RECORD
;
; THIS ROUTINE IS CALLED TO OUTPUT A LINE NUMBER/FILE NAME RECORD
; TO THE OUTPUT FILE. THIS RECORD IS USED TO RESET THE   FILENAME
; AND LINE NUMBER IN PASS 1 DIAGNOSTICS.
;
; USES:
;	R0, R1
;-
 
SHARP:	MOV	#TBUF,R1	;POINT AT TEMP BUFFER
	MOVB	#'#,(R1)+	;PUT '#' IN THE BUFFER
 
	MOV	LINE,R0		;CONVERT
	CALL	$ITOC		;LINE NUMBER
 
	MOV	FILE,R0		;GET FDB POINTER
	CMP	R0,#P0IN	;IF NOT
	BEQ	10$		;STANDARD INPUT
	MOVB	#' ,(R1)+	;OUTPUT
	CALL	$FDBTA		;FILE NAME
 
10$:	SUB	#TBUF,R1	;OUTPUT
	MOV	R1,-(SP)	;PUSH THE BUFFER LENGTH		;04 +
	MOV	#TBUF,-(SP)	;AND THE BUFFER START
	MOV	#P0OUT,R0	;R0 -> THE FILE DATA BLOCK
	CALL	PUTTXT		;DO IT
	BIT	(SP)+,(SP)+	;DUMP THE STACK, KEEP C-BIT	;04 -
	RETURN			;DONE
 

;+
; ** PUTBLN - OUTPUT A BLANK LINE
;
; INPUTS:
;	NONE
;
; OUTPUTS:
;	NONE
;
; USES:
;	R0
;-

PUTBLN:								;02 +
	MOV	#1,-(SP)	;PUSH A SHORT RECORD COUNT	;04 +
	MOV	#BLN,-(SP)	;AND THE BLANK RECORD ADDRESS
	MOV	#P0OUT,R0	;IT GOES TO THIS ONE
	CALL	PUTTXT		;DO IT
	BIT	(SP)+,(SP)+	;TRASH THE STACK		;04 -
	RETURN			;LINE NUMBERS ARE CORRECT	;02 -

;+
; ** EQUAL - COMPARE NAMES
;
; INPUTS:
;	R0=POINTER TO 8 BYTE NAME
;    IDBUF=ANOTHER 8 BYTE NAME
;
; OUTPUTS:
;	C=0 IF THE SAME, C=1 IF DIFFERENT
;
; USES:
;	R0, R1
;-
 
EQUAL:	MOV	#IDBUF,R1	;POINT AT ID BUFFER
 
10$:	CMPB	(R0)+,(R1)+	;EQUAL
	BNE	20$		;NO
	CMP	R1,#IDBUF+8.	;MAYBE
	BLO	10$		;LOOP IF MORE TO COMPARE
	CLC			;EQUAL
	BR	30$		;
 
20$:	SEC			;NOT EQUAL
30$:	RETURN			;RETURN
 
	.END
