/*
 * Copyright (c) 1987 Regents of the University of California.
 * All rights reserved.  The Berkeley software License Agreement
 * specifies the terms and conditions for redistribution.
 */

#ifdef LIBC_SCCS
	<@(#)crt0.s	2.4 (2.11BSD GTE) 2/02/95\0>
	.even
#endif LIBC_SCCS

/*
 * C runtime startoff.  When an a.out is loaded by the kernel, the kernel
 * sets up the stack as follows:
 *
 *	_________________________________
 *	| (NULL)			| 0177776: top of memory
 *	|-------------------------------|
 *	| 				|
 *	| environment strings		|
 *	| 				|
 *	|-------------------------------|
 *	| 				|
 *	| argument strings		|
 *	| 				|
 *	|-------------------------------|
 *	| envv[envc] (NULL)		| end of environment vector tag, a 0
 *	|-------------------------------|
 *	| envv[envc-1]			| pointer to last environment string
 *	|-------------------------------|
 *	| ...				|
 *	|-------------------------------|
 *	| envv[0]			| pointer to first environment string
 *	|-------------------------------|
 *	| argv[argc] (NULL)		| end of argument vector tag, a 0
 *	|-------------------------------|
 *	| argv[argc-1]			| pointer to last argument string
 *	|-------------------------------|
 *	| ...				|
 *	|-------------------------------|
 *	| argv[0]			| pointer to first argument string
 *	|-------------------------------|
 * sp->	| argc				| number of arguments
 *	---------------------------------
 *
 * Crt0 simply moves the argc down two places in the stack, calculates the
 * the addresses of argv[0] and envv[0], putting those values into the two
 * spaces opened up to set the stack up as main expects to see it.
 */


.bss
.globl	_environ		/ copy of envv vector pointer for getenv and
_environ: .=.+2			/   others
.text

/*
 * Paragraph below retained for historical purposes.
 *
 * The following zero has a number of purposes - it serves as a null terminated
 * string for uninitialized string pointers on separate I&D machines for
 * instance.  But we never would have put it here for that reason; programs
 * which use uninitialized pointer *should* die.  The real reason it's here is
 * so you can declare "char blah[] = "foobar" at the start of a C program
 * and not have printf generate "(null)" when you try to print it because
 * blah is at address zero on separate I&D machines ...  sick, sick, sick ...
 *
 * In porting bits and pieces of the 4.4-Lite C library the global program
 * name location '___progname' was needed.  Rather than take up another two
 * bytes of D space the 0th location was used.   The '(null)' string was
 * removed from doprnt.s so now when programs use uninitialized pointers
 * they will be rewarded with argv[0].  This is no sicker than before and
 * may cause bad programs to die sooner.
*/
	.data
	.globl	___progname, _strrchr

___progname: 0
	.text

.globl	_exit, _main


.globl	start
start:
	setd			/ set double precision
	sub	$4,sp		/ make room for argv and env pointers
	mov	sp,r0
	mov	4(sp),(r0)+	/ copy argc down
	mov	sp,(r0)		/ calculate position of arg pointers
	add	$6,(r0)
	mov	*(r0),___progname
	mov	(r0)+,(r0)	/ calculate position of env pointers
	add	(sp),(r0)
	add	(sp),(r0)
	add	$2,(r0)
	mov	(r0),_environ	/ environ = &envv[0]

#ifdef NONFP
.globl	setfpt			/ if non floating point version of the
				/   library, set up floating point simulator
	jsr	pc,setfpt	/   trap - see ../fpsim/README for uglyness
#endif

#ifdef MCRT0
.globl	_etext, _monstartup

	mov	$_etext,-(sp)	/ monstartup(2, &_etext)
	mov	$eprol,-(sp)
	jsr	pc,_monstartup
	cmp	(sp)+,(sp)+
#endif MCRT0

	clr	r5		/ for adb and longjmp/rollback ...
	mov	$'/,-(sp)
	mov	___progname,-(sp)
	jsr	pc,_strrchr
	tst	r0
	beq	1f
	inc	r0
	mov	r0,___progname
1:
	cmp	(sp)+,(sp)+
	jsr	pc,_main	/ call main
	mov	r0,(sp)		/   and pass main's return value to _exit ...
	jsr	pc,*$_exit


#ifdef MCRT0
.globl	_monitor, __cleanup, __exit

_exit:				/ catch call to exit
	clr	-(sp)		/ monitor(0) - write profiling information out
	jsr	pc,_monitor
	jsr	pc,__cleanup	/ the real exit calls _cleanup so we do too
	cmp	(sp)+,(sp)+	/ toss monitor's parameter and our return
	jsr	pc,__exit	/   address leaving the exit code and exit
eprol:				/ start of default histogram recording

#else !MCRT0

/*
 * null mcount and moncontrol,
 * just in case some routine is compiled for profiling
 */
.globl	mcount, _moncontrol
mcount:
_moncontrol:
	rts	pc		/ do nothing

#endif MCRT0
