/ (lgl-
/ 	Mark Williams C for the Atari ST Version 1.0
/ 	Copyright (c) 1984-1986 by Mark Williams Company, Chicago.
/ 	All rights reserved. May not be copied without permission.
/ -lgl)
/
/ ST C run time startup.
/
	.prvd
	.globl	errno_
	.globl	environ_
	.globl	_stksize_
	.globl	_start_
errno_:		.word 0
environ_:	.long	0

/
/ Parse TOS environment list into vector at end of bss.
/	a0 = base of envp[]
/	a1 = past end of envp[] or argv[]
/	a2 = pointer to next word to parse
/	a3 = pointer to last word parsed
/	a4 = unused
/	a5 = base page pointer
/	d0 = base of argv[] if found
/	d1 = terminator character for parse
/	d2 = character temporary
/	d3 = argv found flag
/	_iovector_ = value of ARGV parameter if any
/	environ_ = where envp[] gets stored for getenv()
/	_stksize_ = a long size for stack allocation
/		overwritten at runtime to make a stack limit
/	_start_ = program text base
/

	.shri
_start_:
	movea.l	4(a7), a5		/ Fetch base page pointer
	movea.l	24(a5), a0		/ Fetch bss base
	adda.l	28(a5), a0		/ + size of bss = envp[]
	movea.l	44(a5), a2		/ Fetch environment pointer
	clr.l	d0			/ no argv[]
	movea.l	a0, a1			/ Begin envp[]
	move.l	a2, (a1)		/ Store first element of vector
0:	movea.l	a2, a3
	movea.l	(a1)+, a2
9:	tst.b	(a2)+
	bne.s	9b
	move.l	a2, (a1)
	tst.b	(a2)			/ Test next byte.
	beq.s	1f			/ End of environment
/ Look for ARGV
	cmpi.b	$0x41, (a3)+		/ 'A' ?
	bne.s	0b
	cmpi.b	$0x52, (a3)+		/ 'R' ?
	bne.s	0b
	cmpi.b	$0x47, (a3)+		/ 'G' ?
	bne.s	0b
	cmpi.b	$0x56, (a3)+		/ 'V' ?
	bne.s	0b
/ ARGV found, look for iovector.
	cmpi.b	$0x3D, (a3)+		/ '=' ?
	bne.s	0f
	tst.b	(a3)
	beq.s	0f
	move.l	a3, _iovector_
/ ARGV found, rest of environ is argv[]
0:	clr.l	(a1)+			/ Terminate envp[]
	move.l	a1, d0			/ Save base of argv[]
	move.l	a2, (a1)		/ start of arguments
0:	movea.l	a2, a3
	movea.l	(a1)+, a2
9:	tst.b	(a2)+
	bne.s	9b
	move.l	a2, (a1)
	tst.b	(a2)			/ detect end
	bne.s	0b
/ End of envp[] or envp[] and argv[]
1:	clr.l	(a1)+			/ Terminate argv[] or envp[]
	move.l	d0, d3			/ See if argv[] found
	bne.s	3f
/ ARGV= not found, parse command tail
	move.l	a1, d0			/ Save base of argv[]
	move.l	$_cmdname_, (a1)+	/ Store canned name for argv[0]
	lea	128(a5), a2		/ Command tail buffer == argv[1]
	move.b	(a2)+, d2		/ Fetch count
	ext	d2
	clr.b	0(a2, d2)		/ Nul terminate the cmdtail
	moveq	$0x20, d1		/ Space terminator
0:	move.b	(a2)+, d2		/ If it isn't empty
	beq.s	2f			/ end of command tail
	cmp.b	d1, d2			/ Strip spaces
	beq.s	0b
	subq	$1, a2			/ Unstrip character
	move.l	a2, (a1)+		/ Store into vector
9:	move.b	(a2)+, d2		/ Fetch character
	beq.s	2f			/ end of command tail
	cmp.b	d1, d2			/ Terminator
	bne.s	9b
1:	clr.b	-1(a2)			/ Terminate argv[argc]
	bra.s	0b			/ Continue
2:	clr.l	(a1)+			/ Terminate argv[]
/ Allocate stack, a1 points beyond vectors
3:	move.l	a1, d1			/ Save end of vectors for argc
	adda.l	_stksize_, a1		/ Allocate _stksize_ bytes of stack
	move.l	d1, _stksize_		/ Save end of vectors for stack limit
	movea.l	a1, a7			/ Set the initial stack.
	move.l	a1, 4(a5)		/ Save current brk for sbrk
/ Push arguments for main(argc, argv, envp)
	move.l	a5, -(a7)		/ basepage
	move.l	a0, environ_		/ envp[]
	move.l	a0, -(a7)		/ envp[]
	move.l	d0, -(a7)		/ argv[]
	sub.l	d0, d1			/ (argc+1) * sizeof(char *)
	asr.l	$2, d1			/ (argc+1)
	subq	$1, d1			/ argc
	move	d1, -(a7)
/ Release unused memory to the system pool.
	suba.l	a5, a1			/ Compute size of retained memory
	move.l	a1, -(a7)
	move.l	a5, -(a7)		/ Base of retained memory
	clr	-(a7)			/ Must be zero
	move	$0x4A, -(a7)		/ Mshrink opcode
	trap	$1			/ Gemdos
	adda	$12, a7			/ Pop arguments
/ Fixup the stderr file handle if we're off the desktop
	tst.l	d3
	bne.s	0f
	moveq	$2, d0			/ dup(2)
	move	d0, -(a7)
	jsr	dup_
	moveq	$2, d0
	move	d0, (a7)
	clr	-(a7)			/ dup2(dup(0), 2)
	jsr	dup_
	move	d0, (a7)
	jsr	dup2_
	addq	$4, a7
0:
/ Call main(argc, argv, envp)
	suba	a6, a6			/ Zero frame pointer
	jsr	main_			/ Call main line
	adda	$10, a7			/ Pop arguments
/ Exit with return from main
	move	d0, -(a7)		/ Push status
	jsr	exit_			/ Call extended exit()
	move	$0x4C, -(a7)		/ Terminate
	trap	$1
