*************************************************************************
*									*
*			  Tiny SAS/C Startup Code			*
*			  -----------------------			*
*									*
*			    -------------------				*
*			       Version 1.00				*
*			    -------------------				*
*			     Copyright © 1995				*
*			      Nick Christie.				*
*			    39 St Georges Drive				*
*			    Bransgore BH23 8EZ				*
*			      Great Britain.				*
*			    All Rights Reserved				*
*			    -------------------				*
*									*
* Tab size = 8.								*
*									*
* Version 1.0	(12/07/94)						*
* ========================						*
* Startup for C using a4 base-relative data and registerized parameters	*
* callable from WB or shell. Adapted from SAS/C 5.10 startup "c.a".	*
* Sets up _SysBase and _DOSBase, opens/closes dos.library, initializes	*
* initializes _WBenchMsg. Does not allow stack checking, or set up	*
* __ProgramName, oserr, ONBREAK, etc.					*
* Calls @main (@ == register args) as:					*
*	LONG rc [d0] = @main(char *cmdline [a0], ULONG cmdlen [d0])	*
* Can't use exit(), as it needs other stuff.				*
*									*
* Assembles under GenAm3 with:						*
*	genam INCDIR <whatever> ALINK TinyStart.s			*
* Should assemble easily under other assemblers, me thinks.		*
*									*
*************************************************************************

*************************************************************************
******************************  INCLUDES  *******************************
*************************************************************************

		INCLUDE		"exec/exec.i"
		INCLUDE		"exec/funcdef.i"
		INCLUDE		"exec/exec_lib.i"
		INCLUDE		"dos/dosextens.i"

*************************************************************************
*****************************  REFERENCES  ******************************
*************************************************************************

		XREF		_LinkerDB	; linker defined base value
		XREF		__BSSBAS	; linker defined base of BSS
		XREF		__BSSLEN	; linker defined length of BSS

		XREF		@main		; name of C routine to start

		XDEF		_SysBase	; exec.library base
		XDEF		_DOSBase	; dos.library base
		XDEF		__WBenchMsg	; Workbench Startup Msg

*************************************************************************
*****************************  DEFINITIONS  *****************************
*************************************************************************

ABSEXECBASE	EQU		4

*************************************************************************
********************************  START  ********************************
*************************************************************************
* Called from shell with cmd line info, from WB with nothing.
*
* In:	a0 = ptr to cmd line (if shell)
*	d0 = len of cmd line (if shell)
* Out:	d0 = return code (if shell)
*
*************************************************************************

		SECTION		TEXT,CODE

Start:		movem.l		d1-d6/a0-a6,-(a7)

		move.l		a0,a2			; save command pointer
		move.l		d0,d2			;  and command length
		lea.l		_LinkerDB,a4		; load data base reg
		move.l		ABSEXECBASE.w,a6

		lea.l		__BSSBAS,a3		; get base of BSS seg
		moveq.l		#0,d1
		move.l		#__BSSLEN,d0		; len of BSS in longs
		bra.s		S_ClrBSS2
S_ClrBSS1:	move.l		d1,(a3)+		; clear BSS segment
S_ClrBSS2:	dbra		d0,S_ClrBSS1

		move.l		a6,_SysBase(a4)		; save SysBase
		clr.l		__WBenchMsg(a4)		; clr WB msg ptr

		moveq.l		#0,d0			; clear any pending
		move.l		#$3000,d1		;   signals
		jsr		_LVOSetSignal(a6)

		lea.l		DOSName(pc),a1		; attempt to open
		moveq.l		#0,d0			;  DOS library
		jsr		_LVOOpenLibrary(a6)
		move.l		d0,_DOSBase(a4)
		bne.s		S_DOSOpen

		moveq.l		#100,d2			; if fail, return
		bra.s		S_Return		;  error level 100

S_DOSOpen:	move.l		ThisTask(a6),a3		; ptr to my process
		tst.l		pr_CLI(a3)		; called from WB ?
		bne.s		S_GoMain		; no...

		lea.l		pr_MsgPort(a3),a0	; now wait for and
		jsr		_LVOWaitPort(a6)	;  get the WB startup
		lea.l		pr_MsgPort(a3),a0	;   message...
		jsr		_LVOGetMsg(a6)
		move.l		d0,__WBenchMsg(a4)	; save ptr to WB msg,
		movea.l		d0,a2			;  also into a2
		moveq.l		#0,d2			; cmdlen = 0 for WB

S_GoMain:	movea.l		a2,a0			; move cmdlen and
		move.l		d2,d0			;  cmdline into a0/d0
		jsr		@main(pc)		; call C program

		move.l		d0,d2			; save return code
		movea.l		_SysBase(a4),a6		; load execbase

		tst.l		__WBenchMsg(a4)		; came from WB ?
		beq.s		S_CloseDOS		; nope...
							; yes...reply the WB msg
		jsr		_LVOForbid(a6)		; but Forbid() first so
		movea.l		__WBenchMsg(a4),a1	; WB doesn't UnLoadSeg()
		jsr		_LVOReplyMsg(a6)	;  us before we're done

S_CloseDOS:	movea.l		_DOSBase(a4),a1		; close dos library
		jsr		_LVOCloseLibrary(a6)

S_Return:	move.l		d2,d0			; retrieve return code
		movem.l		(a7)+,d1-d6/a0-a6
		rts

DOSName:	dc.b		'dos.library',0

*************************************************************************
********************************  DATA  *********************************
*************************************************************************

		SECTION		__MERGED,BSS

_SysBase:	ds.l		1
_DOSBase:	ds.l		1
__WBenchMsg:	ds.l		1

		END

