/*
 * This program does load an Elf Binary and runs it as a PPC Task.
 * It doesn`t return until the Task completes.
 * It measures the time the PPCRunObject() function
 * needs.
 *
 */

#include <exec/types.h>
#include <devices/timer.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/timer.h>
#include <PowerUP/pragmas/ppc_pragmas.h>
#include <PowerUP/clib/ppc_protos.h>
#include "PPCLoadTimer_VERSION.h"
#include <stdlib.h>
#include <stdio.h>

UBYTE vers[] = VERSTAG;

extern struct ExecBase	*SysBase;

void	main(ULONG	argc,
             char	*argv[])
{
struct Library		*PPCLibBase;
ULONG			Result;
APTR			MyObject;
ULONG			ticks;
ULONG			allticks,secs,mics;
float			micros;
struct MsgPort		*timermp;
struct timerequest	*timerio;
struct EClockVal	MyOldEClockVal;
struct EClockVal	MyEClockVal;
struct Library		*TimerBase;

  if((argc < 2L) || (argc >3L))
  {
    printf("Usage: Name [Value]\n");
  }
  else
  {
    if ((timermp = CreatePort(NULL, 0)) != NULL)
    {
      if ((timerio = (struct timerequest*) CreateStdIO(timermp)) != NULL)
      {
        if (OpenDevice("timer.device", UNIT_VBLANK, (struct IORequest *)timerio, 0) == 0L)
        {
          TimerBase	=	(struct Library*) timerio->tr_node.io_Device;

          if (PPCLibBase=OpenLibrary("ppc.library",0))
          {
            if (MyObject=PPCLoadObject(argv[1]))
            {
              ticks=ReadEClock(&MyOldEClockVal);

              Result=PPCRunObject(MyObject,
                                  argc ==3 ? (APTR) atoi(argv[2]) : NULL);

              ticks=ReadEClock(&MyEClockVal);

              if (MyEClockVal.ev_hi <= MyOldEClockVal.ev_hi)
              {
                allticks=MyEClockVal.ev_lo - MyOldEClockVal.ev_lo;
              }
              else
              {
                if (MyEClockVal.ev_lo <= MyOldEClockVal.ev_lo)
                {
                  allticks=MyEClockVal.ev_lo - MyOldEClockVal.ev_lo;
                }
                else
                {
                  allticks=MyOldEClockVal.ev_lo - MyEClockVal.ev_lo;
                }
                allticks+=(MyEClockVal.ev_hi - MyOldEClockVal.ev_hi)<<16;
              }

              secs	=	allticks/ticks;
              micros	=	((float) 1/((float) ticks/ (float) ((allticks-(secs*ticks)))))*1000000;
              mics	=	micros;

              printf("RunTime: %ld.%06ld secs\n",secs,mics);
              printf(" Result: 0x%lx : %ld\n",Result,Result);
              PPCUnLoadObject(MyObject);
            }
            else
            {
              printf("Can't load %s\n",argv[1]);
            }
            CloseLibrary(PPCLibBase);
          }
          CloseDevice((struct IORequest *)timerio);
        }
        DeleteStdIO((struct IOStdReq *)timerio);
      }
      DeletePort(timermp);
    }
  }
}
