/* This test program sends 1000 messages to the PPC and
   shows how long this takes.
   The Messages are send asynchron and it`s not waited
   for the reply...until all messages are send
   Each Message has the Body "Text sent by M68k 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 TEXT            "Text sent by M68k processor\n"
#define	MSGCOUNT	1000

struct StartupData
{
	ULONG	MsgCount;
};

extern struct Library	*SysBase;
void			*MsgArray[MSGCOUNT];

int	main(void)
{
struct Library		*PPCLibBase;
struct TagItem		MyTags[10];
void			*PPCPort;
void			*ReplyPort;
void			*StartupMsg;
void			*M68kMsg;
void			*PPCMsg;
void			*ElfObject;
void			*Task;
UBYTE			*Body;
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:Msg5PPC.elf"))
      {
        printf("Creating reply port\n");
        MyTags[0].ti_Tag	=	TAG_DONE;
        if (ReplyPort = PPCCreatePort(MyTags))
        {
          if (StartupMsg = PPCCreateMessage(ReplyPort, 0))
          {
            printf("Allocating StartupData\n");
            if (StartupData = PPCAllocVec(sizeof(struct StartupData), MEMF_ANY))
            {
              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))
              {
                if (PPCPort=(void*) PPCGetTaskAttrsTags(Task,
                                                        PPCTASKINFOTAG_MSGPORT,0,
                                                        TAG_END))
                {
                  printf("Allocating memory for message body\n");
                  if (Body = PPCAllocVec(sizeof(TEXT), MEMF_PUBLIC))
                  {
                    printf("Creating all messages...\n");
                    for (i=0;i<MSGCOUNT;i++)
                    {
                      if ((MsgArray[i]=PPCCreateMessage(ReplyPort,
                                                        sizeof(TEXT)))==NULL)
                      {
                        break;
                      }
                    }

                    if (i>=MSGCOUNT)
                    {
                      strcpy(Body, TEXT);
                      printf("Sending 1000 ASYNCHRON messages with a *Body*...");

                      TimerSetAttr(MyTimerObject,TIMERTAG_START);
                      for (i=0;i<MSGCOUNT;i++)
                      {
                        PPCSendMessage(PPCPort,
                                       MsgArray[i],
                                       Body,
                                       sizeof(TEXT),
                                       0x12345678);
                      }
                      TimerSetAttr(MyTimerObject,TIMERTAG_STOP);
                      TimerShow(MyTimerObject);

                      printf("Wait for 1000 message replies...");
                      TimerSetAttr(MyTimerObject,TIMERTAG_START);

                      i	=	0;

                      while (i<MSGCOUNT)
                      {
                        PPCWaitPort(ReplyPort);
                        while (i<MSGCOUNT && PPCGetMessage(ReplyPort))
                        {
                          i++;
                        }
                      }
                      TimerSetAttr(MyTimerObject,TIMERTAG_STOP);
                      TimerShow(MyTimerObject);

                      printf("Waiting for Task Finish Msg...\n");
                      for (;;)
                      {
                        if ((M68kMsg=PPCGetMessage(ReplyPort)) == 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(ReplyPort);
                        }
                      }
                    }
                    else
                    {
                      Printf("Could not create all msgs\n");
                    }

                    printf("Deleting messages...\n");
                    for (i=0;i<MSGCOUNT;i++)
                    {
                      if (MsgArray[i])
                      {
                        PPCDeleteMessage(MsgArray[i]);
                      }
                    }
                  }
                  else
                  {
                    Printf("Could not alloc mem for msg body\n");
                  }
                  printf("Deleting reply port...");
                  while (PPCDeletePort(ReplyPort) == FALSE);
                }
                else
                {
                  Printf("Could not find the PPCTask's msgport\n");
                }
                printf("Freeing message body memory\n");
                PPCFreeVec(Body);
              }
              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");
          }
        }
        else
        {
          Printf("Could not create reply port\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");
  }
}

