
#include <libraries/dosextens.h>
#include <exec/ports.h>
#include <functions.h>

#include "dos37em.h"


void
ryb_SendPkt (struct DosPacket *packet, struct MsgPort *port,
	     struct MsgPort *replyport)
{
  packet->dp_Port = replyport;
  PutMsg (port, packet->dp_Link);
}


typedef struct Message * (*ptr_func_returning_ptr_msg) ();

struct DosPacket *
ryb_WaitPkt (void)
{
  struct Process *proc;
  struct Message *msg;

  proc = (struct Process *) FindTask (0L);
  if (proc->pr_PktWait)
    msg = (*(ptr_func_returning_ptr_msg)proc->pr_PktWait) ();
  else
    {
      WaitPort(&proc->pr_MsgPort);
      msg = GetMsg(&proc->pr_MsgPort);
    }

  return (struct DosPacket *) msg->mn_Node.ln_Name;
}


struct dos_pkt_args { LONG args[5]; };

LONG
ryb_DoPkt (struct MsgPort *port, LONG action,
	   LONG arg1, LONG arg2, LONG arg3, LONG arg4, LONG arg5)
{
  char stdpkt[sizeof(struct StandardPacket) + 2];
  struct StandardPacket *sp;
  struct Process *proc = (struct Process *) FindTask (0L);

  /* Longword align sp */
  sp = (struct StandardPacket *)(((ULONG)stdpkt + 3) & ~3);

  sp->sp_Msg.mn_Node.ln_Name = (char *) &sp->sp_Pkt;
  sp->sp_Pkt.dp_Link = &sp->sp_Msg;
  sp->sp_Pkt.dp_Type = action;

  /* WARNING: Compiler/OS dependent code ahead. */
  *(struct dos_pkt_args *)&sp->sp_Pkt.dp_Arg1
    = *(struct dos_pkt_args *)&arg1;

  SendPkt (&sp->sp_Pkt, port, &proc->pr_MsgPort);
  (void) WaitPkt ();

  proc->pr_Result2 = sp->sp_Pkt.dp_Res2;
  return sp->sp_Pkt.dp_Res1;
}
