#include <exec/types.h>
#include <exec/memory.h>
#include <Exec/ports.h>
#include <devices/parallel.h>
#include <proto/exec.h>

#include <stdio.h>
#include <stdlib.h>

#define   SAFEMEM
#include "safemem.h"
#include "safemem_parallel.h"

/*
 * Structures required to talk to the parallel device
 */
static struct MsgPort  *st_ParallelMP;
static struct IOExtPar *st_ParallelIO;	
static ULONG            st_ParallelOpen = 0;

/*
 * FUNCTION:
 *   ULONG OpenSafeMemParallel()
 *
 * DESCRIPTION:
 *     Opens the parallel device for use by the SafeMem functions. It is opened
 *   in shared mode, so multiple safemem tasks can exist simulataneously, as
 *   well as Enforcer and MungWall, etc.
 *     If gbl_SafeMem == 0, this function has no effect.
 *     This function changes gbl_SafeMemOutput.
 *
 * RETURNS:
 *   SUCCESS: 1
 *   FAILURE: 0
 *
 * WRITTEN:
 *   Saturday 05-Dec-92 16:28:
 */
ULONG OpenSafeMemParallel()
{
  if(gbl_SafeMem)
  {
    st_ParallelMP=CreatePort(0,0);
    st_ParallelIO=(struct IOExtPar *)CreateExtIO(st_ParallelMP,sizeof(struct IOExtPar));
    st_ParallelIO->io_ParFlags=PARF_SHARED;

    if(OpenDevice("parallel.device", 0, (struct IOStdReq *)st_ParallelIO,0))
    {
      CloseSafeMemParallel();
      return(0);
    }

    st_ParallelOpen = 1;
    gbl_SafeMemOutput = WriteSafeMemParallel;
  }

  return(1);
}

/*
 * FUNCTION:
 *   void CloseSafeMemParallel()
 *
 * DESCRIPTION:
 *   Closes the parallel port. gbl_SafeMemOutput now reverts to _writes().
 *
 * WRITTEN:
 *   Saturday 05-Dec-92 16:30:
 */
void CloseSafeMemParallel()
{
  if(st_ParallelOpen)
  {
    CloseDevice((struct IOStdReq *)st_ParallelIO);
    st_ParallelOpen = 0;
  }
  
  if(st_ParallelIO)
  {
    DeleteExtIO((struct IOExtReq *)st_ParallelIO);
    st_ParallelIO = 0;
  }
  
  if(st_ParallelMP)
  {
    DeletePort(st_ParallelMP);
    st_ParallelMP = 0;
  }
  
  if(gbl_SafeMem)
    gbl_SafeMemOutput = (void (*)())_writes;

  return;
}

/*
 * FUNCTION:
 *   void WriteSafeMemParallel(char *data)
 *
 * DESCRIPTION:
 *     Puts text to the parallel port. Assumes the parallel port has been
 *   opened with OpenSafeMemParallel().
 *
 * ARGUMENTS:
 *   char *data - The text to put
 *
 * WRITTEN:
 *   Saturday 05-Dec-92 16:32:
 */
void WriteSafeMemParallel(char *data)
{
  struct MessagePort *mp;
  struct IOExtPar     req;

  if(st_ParallelOpen)
  {
   /*
    * Create our own IO block & port (since we mightn't be the same task
    * that opened the parallel port in the first place).
    */
    req = *st_ParallelIO;
    mp  = CreatePort(0,0);

   /*
    * Feed the data for a write
    */
    req.IOPar.io_Command  = CMD_WRITE;
    req.IOPar.io_Length   = -1;
    req.IOPar.io_Data     = (APTR)data;
    req.IOPar.io_Message.mn_ReplyPort = mp;

   /*
    * Execute the write & wait for it to finish
    */
    DoIO((struct IOStdReq *)&req);         

   /*
    * Free the port & that's it.
    */
    DeletePort(mp);
  }
}

