/* Startup_c.c */
/* Thu Jun 24 18:05:36 1993 GM TabSize=4
   additional startup code, C part

   No Bugs known

   Does not handle commandline-parsing,

   CLI: argc gets d0 (len) and argv a0 (arguements)

   WB : argc gets 0, argv ptr to WBStartupMessage.
        No window is opened,  _stdin and _stdout get zero. Test for this !

   Thu Sep 23 18:19:55 1993 GM: cleanup
*/

#include <exec/types.h>
#include <exec/libraries.h>
#include <exec/execbase.h>
#include <libraries/dosextens.h>
#include <dos/dos.h>
#include <inline/exec.h>
#include <inline/dos.h>
#include <workbench/startup.h>

extern struct ExecBase *SysBase;
extern struct WBStartup	*WBenchMsg;

extern int main(ULONG,ULONG);

/* called by assember-startup-code */

int _main(UBYTE *reg_a0, ULONG reg_d0)
{
  struct Process	*me		= (struct Process *) SysBase->ThisTask;
  int				exit_val;

  /*
   * The following code to reset the fpu might not be necessary, BUT since
   * a CLI shell doesn't spawn a new process when executing a command - it
   * insteads calls the command like a subroutine - it depends on the Shell
   * whether the fpu is setup correctly. And I don't like to depend on any
   * thing ;-)
   */

  if (SysBase->AttnFlags & AFF_68881)
    /* reset fpu into a defined state */
    asm volatile ("
	moveml	a5/a6,sp@-
	lea	pc@(Lreset_fpu),a5
	addl	#2,a5		| needed due to a bug in as
						| or:	lea	pc@(Lreset_fpu-.+2),a5
	movel	4:w,a6
	jsr	a6@(-30)		| Supervisor()
	bra	Lafter_reset_fpu

Lreset_fpu:
	clrl	sp@-
	frestore sp@+
	rte

Lafter_reset_fpu:
	moveml	sp@+,a5/a6");

  /* first deal with WB messages, since those HAVE to be answered properly,
   * even if we should fail later (memory, whatever..) */

  if (! me->pr_CLI)
  {
      /* we have been started by Workbench. Get the StartupMsg */

      WaitPort (& me->pr_MsgPort);
      WBenchMsg = (struct WBStartup *) GetMsg (& me->pr_MsgPort);

      /* Workbench programs expect to have their CD where the executed
       * program lives. */

      if (WBenchMsg->sm_ArgList)
		{
		  CurrentDir (WBenchMsg->sm_ArgList->wa_Lock);
		}

      /* argc==0: this means, that argv is really a WBenchMsg, not a vector */

		exit_val=main(0L, (ULONG)WBenchMsg);
    }
	else
	{
    	/* We have a CLI-Start here. Since we don't want to blow up
			the startup, the original d0/a0 values are passed to main.
			There further things have to be done if necessary */

	    exit_val=main(reg_d0, (ULONG)reg_a0);
	}


	/* exit is called by the caller */

  return exit_val;
}

