/*
 *  This file is part of ixemul.library for the Amiga.
 *  Copyright (C) 1991, 1992  Markus M. Wild
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#define KERNEL
#include "ixemul.h"

#include <exec/ports.h>
#include <exec/interrupts.h>

struct MsgPort *
CreatePort(const char *name, int pri)
{
  int sigBit;
  struct MsgPort *port;
  
  if ((sigBit = AllocSignal(-1)) == -1) return 0;
  
  port = (struct MsgPort *) kmalloc (sizeof (struct MsgPort));
  if (! port)
    {
      FreeSignal (sigBit);
      errno = ENOMEM;
      return 0;
    }
    
  bzero (port, sizeof (struct MsgPort));
  
  port->mp_Node.ln_Name = name;
  port->mp_Node.ln_Pri = pri;
  port->mp_Node.ln_Type = NT_MSGPORT;
  
  port->mp_Flags = PA_SIGNAL;
  port->mp_SigBit = sigBit;
  port->mp_SigTask = FindTask (0);
  
  if (name)
    AddPort (port);
  else
    NewList (&(port->mp_MsgList));
    
  return port;
}

struct MsgPort *
CreateInterruptPort (const char *name, int pri, void (*code)(), void *data)
{
  struct MsgPort *port;
  struct Interrupt *interrupt;

  if (port = (struct MsgPort *) kmalloc (sizeof (struct MsgPort)))
    {
      if (interrupt = (struct Interrupt *) kmalloc (sizeof (struct Interrupt)))
        {
	  bzero (interrupt, sizeof (struct Interrupt));
          interrupt->is_Node.ln_Type = NT_INTERRUPT;
	  /* as a convenience, if data is 0, set it to the port itself */
          interrupt->is_Data = data ? data : port;
          interrupt->is_Code = code;
          
          bzero (port, sizeof (struct MsgPort));
	  port->mp_Node.ln_Name = name;
	  port->mp_Node.ln_Pri = pri;
	  port->mp_Node.ln_Type = NT_MSGPORT;
          
	  port->mp_Flags = PA_SOFTINT;
	  port->mp_SoftInt = interrupt;

	  if (name)
	    AddPort (port);
	  else
	    NewList (&(port->mp_MsgList));
    
	  return port;
	}
      
      kfree (port);
    }

  errno = ENOMEM;
  return 0;
}
