/* Stefan Burstrom Source and concept
 * Adapted by Ralph Schmidt
 */

#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>

struct StartupData
{
	APTR	M68kPort; /* The PPCTask can send messages here */
	LONG	Status;   /* When the task exits, it can fill in the status here */
};

#define	MSG_END	0x12345678

void main(int	argc,
          char	*argv[])
{
struct TagItem	MyTags[10];
struct Library	*PPCLibBase;
void		*MyObject;
ULONG		MsgID;


  if (PPCLibBase=OpenLibrary("ppc.library",44))
  {
    if (MyObject=PPCLoadObject("PROGDIR:StartupPPC.elf"))
    {
      APTR M68kPort;

      MyTags[0].ti_Tag  = TAG_DONE;
            
      if (M68kPort = PPCCreatePort(MyTags))
      {
        APTR PPCMsg;
        if (PPCMsg = PPCCreateMessage(M68kPort,sizeof(struct StartupData)))
        {
          struct StartupData	*StartupData;
      
          if (StartupData = PPCAllocVec(sizeof(struct StartupData),MEMF_ANY))
          {
            long	quit = FALSE;
            APTR	Task;

            StartupData->M68kPort	=	M68kPort; /* Provide the PPC a way to send us messages */

            MyTags[0].ti_Tag		=	PPCTASKTAG_STARTUP_MSG;
            MyTags[0].ti_Data		=(ULONG) PPCMsg;

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

            MyTags[2].ti_Tag		=	PPCTASKTAG_STARTUP_MSGLENGTH;
            MyTags[2].ti_Data		=	sizeof(struct StartupData);

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

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

            MyTags[5].ti_Tag		=	TAG_END;


            if (Task = PPCCreateTask(MyObject,
                                     MyTags))
            {
              while (!quit)
              {
                APTR	thePPCMsg;


                PPCWaitPort(M68kPort);

                if (thePPCMsg = PPCGetMessage(M68kPort))
                {
                  MsgID	=	PPCGetMessageAttr(thePPCMsg, PPCMSGTAG_MSGID);
                  switch (MsgID)
                  {
                    case MSG_END:
                            /* Handle our reply messages here */
                            /* Since the only message we send is the
                             * startup msg, we quite in all cases    */
                            /* Here we check the return code from the PPC task
                             * We could be abit more sofisticated and display
                             * appropriate message, take actions etc.
                             */
                            Printf("Status from PPCTask: %ld\n",StartupData->Status);
                            quit	=	TRUE;
                            break;

                    default:
                            /* Handle our messages here */
                            /* We should probably do something more interesting here */
                            Printf("The message ID was: %ld\n",PPCGetMessageAttr(thePPCMsg, PPCMSGTAG_MSGID));
                            PPCReplyMessage(thePPCMsg);
                            break;
                  }
                }
              }
            }
            else
            {
              Printf("Unable to create PPC task\n");
            }
            PPCFreeVec(StartupData);
          }
          else
          {
            Printf("Unable to allocate Startup Message\n");
          }
          PPCDeleteMessage(PPCMsg);
        }
        else
        {
          Printf("Unable to create PPC Message\n");
        }
        PPCDeletePort(M68kPort);
      }
      else
      {
        Printf("ERROR: Unable to allocate memory\n");
      }
      PPCUnLoadObject(MyObject);
    }
    else
    {
      Printf("ERROR: Couldn't load PPC Program (PPCMpeg.elf)\n");
    }
    CloseLibrary(PPCLibBase);
  }
  else
  {
    Printf("ERROR: Couldn't open ppc.library\n");
  }
}
