/****** SERL/startup ********************************************************
*
*   NAME
*       startup -- Generic startup code
*
*   SYNOPSIS
*       startup()
*
*       LONG startup(VOID);
*
*   FUNCTION
*       Generic startup routine which can be used to replace the compiler
*       specific startup code.  Unlike the compiler specific startup code,
*       this startup routine does not setup any arguments, stdio or do any
*       other work for the programmer.  Only SysBase and DOSBase will be
*       valid on entry into the program.
*
*       The main entry point prototype is as follows:
*         LONG main(struct Process *process, struct WBStartup *wbstartup);
*
*       The process pointer will always be valid and points to the
*       current process.  The wbstartup pointer can be valid or NULL.
*       A valid wbstartup pointer indicates the program was launched from
*       Workbench.  A NULL wbstartup pointer indicates the program was
*       launched from a shell.  Appropriate parsing of either shell
*       arguments or tool types can then be done.
*
*       The MIN_EXEC_VERSION constant can be used to ensure the program
*       runs on the proper version of the OS.  By default, it is set to
*       the minimum OS version supported by Amiga International.
*
*****************************************************************************
*
* $RCSfile: Startup.c $
* $Revision: 1.1 $
* $Date: 1997/06/29 08:02:46 $
* $Author: ssolie $
*
* Copyright (c) 1997 Software Evolution.  All Rights Reserved.
*/

#include <exec/alerts.h>
#include <exec/execbase.h>
#include <exec/types.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <proto/dos.h>
#include <proto/exec.h>


/*** Global variables ***/
struct ExecBase		*SysBase;
struct DosLibrary	*DOSBase;


/*** Constants ***/
const STRPTR DOS_LIB_STR 		= "dos.library";
const ULONG	 DOS_LIB_VER 		= 0;
const LONG	 SYSBASE_ADDR		= 4;
const UWORD	 MIN_EXEC_VERSION	= 39;


/*** Function prototypes ***/
LONG __saveds startup(VOID);
LONG main(struct Process *process, struct WBStartup *wbstartup);


/*
 * startup -- Main startup routine
 *
 * This function performs the necessary Amiga startup and calls the
 * appropriate entry point.  Returns the error code from the program.
 */
LONG __saveds startup()
{
	struct Process *process;
	struct WBStartup *wbstartup;
	LONG result;

	SysBase	= *(struct ExecBase**)SYSBASE_ADDR;
	process	= (struct Process*)FindTask(NULL);

	/*** Check the version of the OS ***/
	if ( SysBase->LibNode.lib_Version < MIN_EXEC_VERSION )  {
		Alert(AT_Recovery | AG_OpenLib | AO_ExecLib);
		process->pr_Result2 = ERROR_INVALID_RESIDENT_LIBRARY;
		return(RETURN_FAIL);
	}

	/*** Open DOS ***/
	DOSBase = (struct DosLibrary*)OpenLibrary(DOS_LIB_STR, DOS_LIB_VER);
	if ( DOSBase == NULL )  {
		Alert(AT_Recovery | AG_OpenLib | AO_DOSLib);
		process->pr_Result2 = ERROR_INVALID_RESIDENT_LIBRARY;
		return(RETURN_FAIL);
	}

	/*** Find out if we were launched from Workbench or Shell ***/
	if ( process->pr_CLI != NULL )
		wbstartup = NULL;
	else  {
		WaitPort(&process->pr_MsgPort);
		wbstartup = (struct WBStartup*)GetMsg(&process->pr_MsgPort);
	}

	/*** Call the main entry point ***/
	result = main(process, wbstartup);

	/*** Perform clean up operations ***/
	CloseLibrary(DOSBase);
	if ( wbstartup != NULL )  {
		Forbid();		/* ensure Workbench doesn't UnLoadSeg() us */
		ReplyMsg((struct Message*)wbstartup);
	}

	return(result);
}
