#include <exec/types.h>
#include <string.h>

#include <devices/serial.h>
#include <devices/tpt.h>

#include <proto/exec.h>

#define READSER_SIG (1L << RSPort->mp_SigBit)

extern BOOL                SERGOOD;

extern long                tptflags;
extern long                readsersig;

extern struct IOExtSer    *ReadSER;
extern struct IOExtSer    *WriteSER;

extern UBYTE               localflag;
extern UBYTE               mybuf[3][AUXBUFSIZE];

extern   void  NiceAbort(struct IORequest *);
extern   void  TDebug(char *);

struct MsgPort     *RSPort = NULL;
struct MsgPort     *WSPort = NULL;

void                EmptySerBuffer(void);

///   OpenSer
BOOL OpenSer(UBYTE * sername, ULONG serunit, ULONG serflags)
{
   if (RSPort = (struct MsgPort *) CreateMsgPort())
   {
      if (ReadSER = (struct IOExtSer *) CreateIORequest(RSPort, sizeof(struct IOExtSer)))
      {
         if (WSPort = (struct MsgPort *) CreateMsgPort())
         {
            if (WriteSER = (struct IOExtSer *) CreateIORequest(WSPort, sizeof(struct IOExtSer)))
            {
               ReadSER->io_SerFlags = serflags;

               if (!OpenDevice(sername, serunit, (struct IORequest *) ReadSER, NULL))
               {
                  ReadSER->io_SerFlags = serflags;
                  ReadSER->io_ReadLen = 8;
                  ReadSER->io_WriteLen = 8;
                  ReadSER->io_BrkTime = 250000;
                  ReadSER->IOSer.io_Command = SDCMD_SETPARAMS;
                  DoIO((struct IORequest *) ReadSER);

                  movmem(ReadSER, WriteSER, (long) sizeof(struct IOExtSer));

                  WriteSER->IOSer.io_Command = CMD_WRITE;
                  WriteSER->IOSer.io_Message.mn_ReplyPort = WSPort;

                  readsersig = READSER_SIG;
// debug
//                  TDebug("OpenSer: Device opened OK.");
// end debug
                  return (TRUE);
               }
            }
            DeleteIORequest((struct IORequest *) WriteSER);
         }
         DeleteMsgPort(WSPort);
      }
      DeleteIORequest((struct IORequest *) ReadSER);
   }
   DeleteMsgPort(RSPort);
// debug
   TDebug("OpenSer: Open device failed");
// end debug
   return (FALSE);
}
//-
///   CloseSer
void CloseSer(void)
{
   if (localflag)
   {
// debug
//      TDebug("CloseSer: Closed serial port (local)");
// end debug
      return;
   }

   if (!SERGOOD)
      return;

   if (tptflags & T_WRITE_PEND)
      WaitIO((struct IORequest *) WriteSER);
   
   if (!(tptflags & T_TYPEAHEAD_FULL))
      NiceAbort((struct IORequest *) ReadSER);

   EmptySerBuffer();

   CloseDevice((struct IORequest *) ReadSER);

   DeleteIORequest((struct IORequest *) WriteSER);
   DeleteIORequest((struct IORequest *) ReadSER);

   DeleteMsgPort(WSPort);
   DeleteMsgPort(RSPort);

   ReadSER = NULL;
   WriteSER = NULL;
   WSPort = NULL;
   RSPort = NULL;
// debug
//   TDebug("CloseSer: Closed serial device");
// end debug
   return;
}
//-
///   EmptySerBuffer
void EmptySerBuffer(void)
{
   long len;

   for (;;)
   {
      ReadSER->IOSer.io_Command = SDCMD_QUERY;
      DoIO((struct IORequest *) ReadSER);

      ReadSER->IOSer.io_Command = CMD_READ;
      ReadSER->IOSer.io_Data = (APTR) mybuf[0];
      len = ReadSER->IOSer.io_Actual;
      
      if (!len)
         break;

      if (len > 255)
         len = 255;
      
      ReadSER->IOSer.io_Length = len;
      DoIO((struct IORequest *) ReadSER);
   }

// debug
//   TDebug("EmptySerBuffer: Flushed serial I/O port");
// end debug

   return;
}
//-
