	.TITLE	CC000
	.IDENT	/X01/
 
	.NLIST	BEX
	.ENABL	LC
 
;
; C COMPILER
; PARSE COMMAND LINE
;
; VERSION X01
;
; DAVID G. CONROY	13-JAN-78
; LAST UPDATED:		24-MAY-79
;
 
	.GLOBL	CC000
	.GLOBL	CSI
	.GLOBL	DFNB1
	.GLOBL	DFNB2

	.MCALL	CALL
	.MCALL	CALLR
	.MCALL	RETURN
	.MCALL	FDAT$R
	.MCALL	FDOP$R
	.MCALL	FINIT$
	.MCALL	CSI$
	.MCALL	CSI$1
	.MCALL	CSI$2
	.MCALL	OPEN$A
	.MCALL	OPEN$W
	.MCALL	OPEN$R
	.MCALL	OFNB$W
	.MCALL	CLOSE$
	.MCALL	NMBLK$
	.MCALL	DIR$
	.MCALL	WTSE$S
	.MCALL	GMCR$
	.MCALL	QIO$

	CSI$

;
; EQUIVALENCES
;

BLANK	=	40		;ASCII BLANK
CR	=	15		;ASCII CARRIAGE RETURN
ALT	=	33		;ASCII ALTMODE
DOL	=	44		;ASCII DOLLAR SIGN

;
; LOCAL DATA
;

SFILE:	.WORD	0		;PTR TO SOURCE FILE
APPEND:	.WORD	0		;FLAG FOR '>>'
EFILE:	.WORD	TI		;PTR TO ERROR FILE
IOS:	.BLKW	2		;IO STATUS BLOCK

SRC:	.RAD50	/SRC/		;FILETYPES
INT:	.RAD50	/INT/		;
ASM:	.RAD50	/S  /		;
 
CSI:	.BLKB	C.SIZE		;CSI WORK BLOCK
DFNB1:	NMBLK$	,,,SY		;DEFAULT FILENAME BLOCKS
DFNB2:	NMBLK$	,C,,SY		;
GMCR:	GMCR$			;GET MCR COMMAND LINE BLOCK
GMCRP:	QIO$	IO.WVB,1,1,,,,<PRM,4,44> ;PROMPT QIO DPB
GMCRR:	QIO$	IO.RVB,1,1,,IOS,,<GMCR+G.MCRB,79.> ;READ LINE

;
; ASCII DATA.
;

TI:	.ASCIZ	'TI:'
PRM:	.ASCIZ	'CCX>'
MSG01:	.ASCIZ	'Usage: cc [-dilmpstv] file'
MSG02:	.ASCIZ	'Cannot open error file'
MSG03:	.ASCIZ	'Cannot open input file'
MSG04:	.ASCIZ	'Cannot open intermediate file'
MSG05:	.ASCIZ	'Cannot open output file'
MSG06:	.ASCIZ	'?: Ignored'
 
	.EVEN

;+
; ** CC000 - PARSE COMMAND LINE
;
; THIS ROUTINE IS CALLED BY THE ROOT. IT READS THE MCR COMMAND LINE
; (PERHAPS GETTING IT FROM THE USER TI:, IF THE GMCR$ FAILS).  THEN
; IT PARSES IT INTO ARGUMENTS, SETTING THE OPTION FLAGS.
;
; THE ERROR STREAM IS OPENED ON THE EFDB. A TEMP FILE IS OPENED FOR
; WRITING ON THE SFDB, THE USER'S SOURCE IS OPENED ON THE AFDB, AND
; THE PREPROCESSOR (CCPREP) IS CALLED.
;
; THE USER'S SOURCE FILE IS THEN CLOSED. THE IFDB AND AFDB, USED IN
; PREPROCESSING, ARE OPENED UP AS THE INTERMEDIATE CODE AND  OUTPUT
; FILES. CONTROL RETURNS TO THE ROOT.
;-

CC000:	FINIT$			;INITIALISE THE FSR
 
	DIR$	#GMCR		;GET MCR LINE
	BCC	20$		;OK
 
10$:	DIR$	#GMCRP		;PROMPT FOR THE LINE
	WTSE$S	#1		;
	DIR$	#GMCRR		;READ IT BACK
	WTSE$S	#1		;
	CMP	IOS,#IS.CR	;WAS THE LINE GOOD
	BNE	10$		;NO
	MOV	IOS+2,R0	;PUT CR ON THE END
	MOVB	#CR,GMCR+G.MCRB(R0) ;FOR THE SCAN
 
20$:	MOV	#GMCR+G.MCRB,R0	;POINT TO THE LINE
30$:	MOVB	(R0)+,R1	;SKIP OVER COMMAND NAME
	CMPB	R1,#CR		;
	BEQ	130$		;DONE
	CMPB	R1,#ALT		;
	BEQ	130$		;DONE
	CMPB	R1,#BLANK	;
	BNE	30$		;KEEP LOOKING
 
40$:	MOVB	(R0)+,R1	;SKIP
	CMPB	R1,#BLANK	;BLANKS BETWEEN
	BEQ	40$		;ARGS
	CMPB	R1,#CR		;
	BEQ	130$		;DONE
	CMPB	R1,#ALT		;
	BEQ	130$		;DONE
 
	CMPB	R1,#'-		;OPTIONS
	BNE	60$		;NO
50$:	MOVB	(R0)+,R1	;OPTION CHARACTER
	CMPB	R1,#CR		;
	BEQ	130$		;DONE
	CMPB	R1,#ALT		;
	BEQ	130$		;DONE
	CMPB	R1,#BLANK	;
	BEQ	40$		;GO GET THE NEXT ARG.
	CALL	OPT		;PROCESS OPTIONS
	BR	50$		;
 
60$:	CLR	R2		;CLEAR QUOTES FLAG
	CMPB	R1,#'"		;CHECK FOR QUOTES
	BEQ	70$		;
	CMPB	R1,#''		;
	BNE	80$		;BR IF NOT A QUOTE
70$:	MOV	R1,R2		;SAVE QUOTE DELIMITER
	TST	SFILE		;DO WE HAVE A FILE
	BNE	140$		;YES, ERROR
	MOV	R0,SFILE	;SAVE THE FILE POINTER
	BR	90$		;GO COLLECT NAME
 
80$:	CMPB	R1,#'<		;INPUT REDIRECTION
	BEQ	90$		;IS DISCARDED
	CMPB	R1,#'>		;OUTPUT REDIRECTION
	BNE	85$		;NO
	CMPB	R1,(R0)		;IS THIS '>>'
	BNE	82$		;NO
	INC	APPEND		;SET APPENDING
	INC	R0		;SKIP OVER THE SECOND '>'
82$:	MOV	R0,EFILE	;SAVE ERROR FILE NAME
	BR	90$		;GO GET NAME
 
85$:	TST	SFILE		;DO WE HAVE A FILE
	BNE	140$		;YES, ERROR
	MOV	R0,SFILE	;SET POINTER
	DEC	SFILE		;
 
90$:	MOVB	(R0)+,R1	;COLLECT THE ARG.
	CMPB	R1,#CR		;
	BEQ	110$		;DONE
	CMPB	R1,#ALT		;
	BEQ	110$		;DONE
	TST	R2		;QUOTED ARGUMENT
	BNE	100$		;BR IF YES
	CMPB	R1,#BLANK	;STOP ON BLANKS
	BEQ	110$		;DONE
	BR	90$		;KEEP GOING
100$:	CMP	R1,R2		;STOP ON MATCHING QUOTE
	BNE	90$		;KEEP GOING
 
110$:	CLRB	-1(R0)		;MAKE ARG ASCIZ
	CMPB	R1,#CR		;CHECK FOR END OF LINE
	BEQ	120$		;DONE
	CMPB	R1,#ALT		;
	BNE	40$		;GO GET NEXT ARG
120$:	TST	R2		;CHECK FOR MISMATCHED QUOTES
	BNE	140$		;ERROR
 
130$:	TST	SFILE		;DID WE GET A FILE
	BNE	200$		;BR IF YES
140$:	MOV	#MSG01,R0	;COMMAND LINE BOTCH
	JMP	300$		;ERROR EXIT
 
;
; OPEN ERROR STREAM.
;
 
200$:	MOV	EFILE,R0	;FILE NAME
	CALL	DSPT		;BUILD THE DSPT
	BCS	220$		;URK
 
	MOV	#EFDB,R0	;GET PTR TO THE FDB
	FDAT$R	,#R.VAR,#FD.CR	;SET RECORD ATTRIBUTES
	FDOP$R	,,#CSI+C.DSDS	;DATASET DESCRIPTOR
	FDOP$R	,,,#DFNB1	;DEFAULT FILENAME BLOCK
	TST	APPEND		;APPENDING
	BEQ	210$		;NO
	OPEN$A			;TRY OPEN FOR APPEND
	BCC	230$		;WORKED
	CMPB	F.ERR(R0),#IE.NSF ;IS THE ERROR NO FILE
	BNE	220$		;NO, HARD ERROR
210$:	OPEN$W			;TRY OPEN FOR WRITE
	BCC	230$		;OK
 
220$:	MOV	#MSG02,R0	;CANNOT CREATE ERROR FILE
	BR	300$		;
 
;
; PREPROCESSING.
;
 
230$:	MOV	SFILE,R0	;GET SOURCE FILE NAME
	CALL	DSPT		;
	BCS	240$		;URK

	MOV	#AFDB,R0	;OPEN FILE
	FDOP$R	,,#CSI+C.DSDS	;DATASET DESCRIPTOR
	FDOP$R	,,,#DFNB2	;DEFAULT FILENAME BLOCK (.C)
	OPEN$R			;
	BCC	250$		;OK

240$:	MOV	#MSG03,R0	;CANNOT OPEN INPUT FILE
	BR	300$		;
 
250$:	CLR	SFDB+F.FNB	;CLEAR OLD FILE ID
	MOV	#AFDB+F.FNB+N.FNAM,R0 ;POINT AT FILE NAME IN FNB
	MOV	#SFDB+F.FNB+N.FNAM,R1 ;POINT AT FILE NAME IN FNB
260$:	MOV	(R0)+,(R1)+	;COPY FNB
	CMP	R0,#AFDB+F.FNB+S.FNB ;
	BLO	260$		;
	MOV	SRC,SFDB+F.FNB+N.FTYP ;BUT MAKE IT .SRC

	MOV	#SFDB,R0	;SET UP ATTRIBUTES
	FDAT$R	,#R.VAR,#FD.CR	;
	OFNB$W			;OPEN THE FILE
	BCC	270$		;OK

	MOV	#MSG04,R0	;CANNOT CREATE TEMP. FILE
	BR	300$		;

270$:	CALL	CCPREP		;DO PREPROCESSING
 
	CLOSE$	#AFDB		;CLOSE USER'S SOURCE
 
;
; OPEN OUTPUT FILES.
;
 
	CLR	AFDB+F.FNB	;CLEAR FILE ID
	MOV	#AFDB+F.FNB+N.FNAM,R0 ;POINT TO NAME
	CLR	IFDB+F.FNB	;CLEAR FILE ID
	MOV	#IFDB+F.FNB+N.FNAM,R1 ;POINT TO NAME
280$:	MOV	(R0)+,(R1)+	;COPY FNB
	CMP	R0,#AFDB+F.FNB+S.FNB ;
	BLO	280$		;
	MOV	INT,IFDB+F.FNB+N.FTYP ;THEN SET FILETYPES
	MOV	ASM,AFDB+F.FNB+N.FTYP ;
 
	MOV	#IFDB,R0	;GET TEMP FILE
	FDAT$R	,#R.VAR,#FD.CR	;
	OFNB$W			;
	BCC	290$		;

	MOV	#MSG04,R0	;CANNOT GET TEMP FILE
	BR	300$		;
 
290$:	MOV	#AFDB,R0	;OPEN OUTPUT FILE
	FDAT$R	,#R.VAR,#FD.CR	;
	OFNB$W			;
	BCC	310$		;

	MOV	#MSG05,R0	;CANNOT OPEN OUTPUT FILE
300$:	CALL	CCTTY		;WRITE ERROR TO TI:
	INC	NERRS		;MAKE THE COMPILER EXIT
310$:	RETURN			;
 
;+
; ** OPT - PROCESS COMMAND OPTIONS
;
;	-D		DEBUG
;	-I		RETAIN INTERMEDIATE FILE
;	-S		RETAIN EXPANDED SOURCE FILE
;	-V		ECHO BAD SOURCE LINES
;	-P		PROFILE
;	-T		GENERATE SYMBOL TABLES
;
; INPUTS:
;	R1=OPTION CHARACTER
;-
 
OPT:	MOV	R0,-(SP)	;MAY NEED THIS REGISTER
	BIC	#BLANK,R1	;MAKE UPPER CASE
 
	CMP	R1,#'D		;-D
	BNE	5$		;NO
	INCB	DFLAG		;SET DEBUG FLAG
	BR	50$		;

5$:	CMP	R1,#'I		;-I
	BNE	6$		;NO
	INCB	IFLAG		;SET FLAG
	BR	50$		;

6$:	CMP	R1,#'L		;-L
	BNE	10$		;NO
	INCB	LFLAG		;SET FLAG
	BR	50$		;

10$:	CMP	R1,#'V		;-V
	BNE	20$		;NO
	INCB	VFLAG		;SET FLAG
	BR	50$		;

20$:	CMP	R1,#'P		;-P
	BNE	30$		;NO
	INCB	PFLAG		;SET FLAG
	BR	50$		;

30$:	CMP	R1,#'S		;-S
	BNE	35$		;NO
	INCB	SFLAG		;SET FLAG
	BR	50$		;

35$:	CMP	R1,#'T		;-T
	BNE	37$		;NO
	INCB	TFLAG		;SET FLAG
	BR	50$		;

37$:	CMP	R1,#'M		;-M
	BNE	40$		;NO
	INCB	MFLAG		;SET FLAG
	BR	50$		;

40$:	MOVB	R1,MSG06	;ILLEGAL OPTION
	MOV	#MSG06,R0	;COMPLAIN
	CALL	CCTTY		;
 
50$:	MOV	(SP)+,R0	;RETURN
	RETURN			;

;+
; ** DSPT - BUILD A DSPT
;
; GIVEN AN ASCII FILE NAME STRING, THIS ROUTINE USES THE MIGHTY CSI
; TO BUILD A DSPT IN THE CSI WORK BLOCK.
; WHY FCS REQUIRES A DSPT IS BEYOND ME.
;
; INPUTS:
;	R0=PTR TO FILENAME STRING
;
; USES:
;	R0
;-
 
DSPT:	MOV	R0,CSI+C.CMLD+2	;SET ADDRESS OF COMMAND LINE
 
10$:	TSTB	(R0)+		;FIND THE LENGTH
	BNE	10$		;
	DEC	R0		;
	SUB	CSI+C.CMLD+2,R0	;
	MOV	R0,CSI+C.CMLD	;AND PUT IN THE CSI BLOCK
 
	CSI$1	#CSI		;DO NASTY WORK
	BCS	20$		;
	CSI$2	,OUTPUT		;
20$:	RETURN			;DONE

	.END
