	.title	$$init	One-time initialization code
	.ident	"V02.01"
;+
; Index		C program initialization
;
; Usage
;
;    Internal
;
;	$$init()
;
; Description
;
;	This is a one-time initialization routine for C programs. It
;	sets up the trap vectors, initializes the free memory pointers,
;	determines the task name, assigns the terminal lun to 1, prompts
;	for a command line if one was not given and proceeds to parse
;	the command line if one was given and form the argv[] array.
;	argv[0] is set to the task name.
;
; Diagnostics
;
;	No memory
;
;	   This message suggests a severe case of program
;	   immensity.
;
;	Cannot parse command line
;
;	   The user supplied an illegal command line.
;-
; Edit history:
; V02.00 19-Oct-82 TTC		Rework of old CS library.
; V02.01 25-Jan-83 TTC		Fixed argv[0] (task name) bug.
;
	.mcall	GPRT$S,	GTSK$S,	ALUN$S, QIOW$S, SVTK$S

MAXMCR	=	80.		; Mcr command line size
R.PARM	=	30		; RSX emulator chain line number

SPACE	=	40

	.psect	c$data

iosb:	.word	0,0
nullst:	.word	0

$$erec::
	.blkw	41.		; used by GTSK

$$esiz	==	.-$$erec	; Error record size

badmem:	.asciz	<015><012>/?????? - No memory./<12>
memsz	=	. - badmem
badcmd:	.asciz	<015><012>/?????? - Cannot parse command line./<12>
cmdsz	=	. - badcmd
	.even

	.psect	c$code
$$init::
	jsr	r5,csv$		; Link environments
;
; Set up the sst vector.
;
	SVTK$S	#$$sstt,#10	; Table is in "traps" module
;
; Initialize free memory pointers
;
	sub	#3*2,sp		; Get partition return area
	mov	sp,r1		; r1 -> gprt$ buffer
	GPRT$S	,r1		; Get partition parameters
	mov	2(r1),r1	; Partition size in clicks
	ash	#6,r1		; Shift left to mul. by 32
	add	$dsw,r1		; Top of memory (correctly)
	mov	r1,$$mend	; Save true top of memory
	add	#3*2,sp		; Dump the stack
;
; Do a get task to get the task name and default UIC
;
	GTSK$S	#$$erec		; Get task parameters
	mov	#2,(sp)		; Get task name (2 words)
	mov	#$$erec+<0.*2>,-(sp) ; From here
	mov	#$$task,-(sp)	; To here
	call	r50toa		; Using C library routine
	cmp	(sp)+,(sp)+	; Cleanup stack
	clr	(sp)		; Assume no task name needed		;01
	mov	$$erec+<7.*2>,$$uic ; Default uic word (word 07)
;
; Allocate the output buffer to the default size
;
	mov	#$$bsiz,-(sp)	; Push default buffer size
	call	outbuf		; call allocation routine
	tst	(sp)+

;
; Assign terminal lun
;
	ALUN$S	#tty.lun,#"TI,#0
;
; Get command line.
;
	mov	#MAXMCR+2,r0	; Get command line buffer
	call	$$aloc
	tst	r0		; zero means trouble
	bne	20$		; Ok, continue
	mov	#$$task,r0	; Put task name into
	mov	#badmem,r1	; error message.
	add	#2,r1
10$:	movb	(r0)+,(r1)+
	tstb	(r0)		; End of task name?
	bne	10$		; (no)
	mov	#memsz,-(sp)	; push error message size
	mov	#badmem,-(sp)	; and error meassage
	jmp	fail		; Exit.

20$:
	mov	r0,-(sp)	; Push GMCR buffer adderss
	mov	(pc)+,(r0)	; Fake MCR dispatch (GMCR$S)
	.byte	127.,41.	; as RSX can't do it at runtime
	emt	377
	bcs	30$		; Branch if failure
	mov	$dsw,r1		; r1 has number of bytes
	add	r0,r1		; r1 --> last byte in buffer
	clrb	2(r1)		; nullify it
	br	domcr		; continue onward

30$:	tst	$$narg		;Really want a command line?
	bne	80$		;If ne, supresss prompt, and go on.
	mov	#$$task,r2	;get address of our task name
	mov	r0,r1		;copy mcr buffer address
	tst	(r1)+		;bump up by two
	mov	(r2)+,(r1)+	;Copy task name
	mov	(r2)+,(r1)+
	mov	(r2)+,(r1)+
40$:	cmpb	#SPACE,-(r1)	;Any spaces in the name?
	beq	40$		;Check 'em all
;
; Note: the above loop depends on the fact that the GMCR directive
; has put a non-space character (actually, '1') at the left end of
; the MCR buffer.
;
	inc	r1		;r1 -> first blank character
	mov	r1,r2		;Save location
	movb	#'>,(r1)+	;Make it look like an RSX prompt
	movb	#SPACE,(r1)	;Space it out a little
	sub	r0,r2		;Get length with terminators
	tst	(r0)+		;Skip over GMCR DPB code
	tst	$$prmt		;User supply prompt?
	beq	55$		;No, use task name
	mov	$$prmt,r3	;r3 --> user prompt string
	clr	r2		;r2 used for prompt length
45$:	tstb	(r3)+		;end of string?
	beq	50$		;yes
	inc	r2		;no, count it
	br	45$		;keep goin'
50$:	qiow$s	#IO.WVB,#1,#1,,#iosb,,<$$prmt,r2,#'$>	; prompt for args
	br	60$
55$:	qiow$s	#IO.WVB,#1,#1,,#iosb,,<r0,r2,#'$>	; prompt for argv
60$:	bcs	80$		;No arg line if error
	tst	-(r0)		;Reset pointer to the buffer
	movb	#SPACE,-1(r1)	;Overwrite the '>'
	qiow$s	#IO.RVB,#1,#1,,#iosb,,<r1,#maxmcr-10>	; read command line
	bcs	80$		;No command if error
	cmpb	iosb,#IS.SUC	;Finish ok?
	bne	80$		;No command if error finish
	add	iosb+2,r1	;Point to the end of the string
	clrb	(r1)		;Terminate the string
	clr	(sp)		;Task name is in buffer, so don't pass another
	br	domcr
80$:
;
; No GMCR command line.
;
	mov	#$$task,(sp)	; Make sure there is a task name
	call	$$free		; If no line, release buffer
	mov	#nullst-2,r0	; Point to null string

domcr:	mov	#$$argv,-(sp)	; Gets argv pointer
	tst	(r0)+		; Point at command line
	mov	r0,-(sp)	; And stuff it, too
;
; Common code -- parse the command line
;
docmd:	call	$$gcmd		; Parse it
	cmp	r0,#-1		; Badly parsed?
	beq  	cmderr		; Sorry.
	mov	r0,$$argc	; and save the count
	add	#<3*2>,sp	; Clear the stack
	jmp	cret$		; All finished

cmderr:	mov	#$$task,r0	; Put task name
	mov	#badcmd,r1	; into error message.
	tst	(r1)+
90$:	movb	(r0)+,(r1)+
	tstb	(r0)		; End of task name?
	bne	90$		; (no)
	mov	#cmdsz,-(sp)	; Push message size
	mov	#badcmd,-(sp)	; and address on stack
fail:	call	ttosf		; and output to terminal.
	jmp	$$fail		; Exit.

	.end
