/* This test program sends 1000 messages to the M68k and
   shows how long this takes.
   The Messages are send synchron and every msg must
   be replied after another.
   Each Message has the Body "Text sent by PPC processor\n"
 */

#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/memory.h>
#include <utility/tagitem.h>
#include <powerup/ppclib/interface.h>
#include <powerup/ppclib/message.h>
#include <powerup/ppclib/tasks.h>
#include <powerup/proto/ppc.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <stdio.h>
#include <string.h>
#include "time.h"
#include "time_protos.h"

#define	MSGCOUNT	1000

struct StartupData
{
	void	*MsgPort;
	ULONG	MsgCount;
};

extern struct Library	*SysBase;

int	main(void)
{
struct Library		*PPCLibBase;
struct TagItem		MyTags[10];
void			*M68kPort;
void			*StartupMsg;
void			*M68kMsg;
void			*ElfObject;
void			*Task;
struct StartupData	*StartupData;
void			*MyTimerObject;
ULONG			i;

  printf("Opening ppc.library\n");
  if (PPCLibBase = OpenLibrary("ppc.library", 44))
  {
    if (MyTimerObject=TimerCreateObject())
    {
      printf("Loading PPC object\n");
      if (ElfObject=PPCLoadObject("PROGDIR:Msg4PPC.elf"))
      {
        MyTags[0].ti_Tag	=	TAG_DONE;
        if (M68kPort = PPCCreatePort(MyTags))
        {
          if (StartupMsg = PPCCreateMessage(M68kPort, 0))
          {
            printf("Allocating StartupData\n");
            if (StartupData = PPCAllocVec(sizeof(struct StartupData), MEMF_ANY))
            {
              StartupData->MsgPort	=	M68kPort;
              StartupData->MsgCount	=	MSGCOUNT;

              printf("Creating PPC task\n");
              MyTags[0].ti_Tag		=	PPCTASKTAG_STARTUP_MSG;
              MyTags[0].ti_Data		=(ULONG) StartupMsg;

              MyTags[1].ti_Tag		=	PPCTASKTAG_STARTUP_MSGDATA;
              MyTags[1].ti_Data	=(ULONG) StartupData;

              MyTags[2].ti_Tag		=	PPCTASKTAG_STARTUP_MSGLENGTH;
              MyTags[2].ti_Data		=	0;

              MyTags[3].ti_Tag		=	PPCTASKTAG_STARTUP_MSGID;
              MyTags[3].ti_Data		=	0;

              MyTags[4].ti_Tag		=	PPCTASKTAG_MSGPORT;
              MyTags[4].ti_Data		=	TRUE;

              MyTags[5].ti_Tag		=	TAG_DONE;

              if (Task = PPCCreateTask(ElfObject, MyTags))
              {
                printf("Sending 1000 SYNCHRON messages with a *Body* and wait for each reply...");

                TimerSetAttr(MyTimerObject,TIMERTAG_START);

                for (i=0;i<MSGCOUNT;i++)
                {
                  PPCWaitPort(M68kPort);
                  while (M68kMsg=PPCGetMessage(M68kPort))
                  {
                    PPCReplyMessage(M68kMsg);
                  }
                }
                TimerSetAttr(MyTimerObject,TIMERTAG_STOP);
                TimerShow(MyTimerObject);

                printf("Waiting for Task Finish Msg...\n");
                for (;;)
                {
                  if ((M68kMsg=PPCGetMessage(M68kPort)) == StartupMsg)
                  {
                    printf("Ahh..the expected Startup=Finish Msg was received.\nNow we can savely free all resources.\n");
                    break;
                  }
                  else
                  {
                    printf("Some non replied Msg 0x%lx was found..wait\n",
                           M68kMsg);
                    PPCWaitPort(M68kPort);
                  }
                }
              }
              else
              {
                Printf("Could not create PPC task\n");
              }
              PPCFreeVec(StartupData);
            }
            else
            {
              Printf("Could not alloc Startup Data\n");
            }
            PPCDeleteMessage(StartupMsg);
          }
          else
          {
            Printf("Could not create Startup message\n");
          }
          printf("Deleting message port...");
          while (PPCDeletePort(M68kPort) == FALSE);
        }
        else
        {
          Printf("Could not create M68k MsgPort\n");
        }
        printf("Unloading PPC object\n");
        PPCUnLoadObject(ElfObject);
      }
      else
      {
        Printf("Could not load the elfobject\n");
      }
      TimerDeleteObject(MyTimerObject);
    }
    printf("Closing ppc.library\n");
    CloseLibrary(PPCLibBase);
  }
  else
  {
    Printf("Could not open ppc.library v44+\n");
  }
}

