#include "bbs.h"

//extern int TimeOut, SerEcho, Local;   not used
LONG GetBufSize(void);
// UBYTE GUB1;
UBYTE serin[20];

struct CIA *cia_ptr;

int OpenSerial(ULONG Baud, UBYTE DataLen, UBYTE StopBits)
{
// if(SEROUT) return(FALSE);  (RTS) already open
 SEROUT=0;
if(Cmds->SerDev[0]!='\0')
	{
	cia_ptr = (struct CIA *)0xBFD000;
	if(ReadSerPort = CreatePort(NULL,0L))
		{
		if(ReadSerReq  = (struct IOExtSer *)CreateExtIO(ReadSerPort,(long)sizeof(struct IOExtSer)))
			{
			if(WriteSerPort= CreatePort(NULL,0L))
				{
				if(WriteSerReq = (struct IOExtSer *)CreateExtIO(WriteSerPort,(long)sizeof(struct IOExtSer)))
					{
					ReadSerReq->io_SerFlags = (SERF_SHARED|SERF_XDISABLED|SERF_RAD_BOOGIE|(!Cmds->AcLvl[LVL_VARYING_LINK_RATE]*SERF_7WIRE));
retry:
					if(!(GI1 = OpenDevice(Cmds->SerDev,(ULONG)Cmds->SerDevUnit,ReadSerReq,(ULONG)0L)))
						{
						Delay((long)10L);

						*WriteSerReq=*ReadSerReq;
						WriteSerReq->IOSer.io_Message.mn_ReplyPort=WriteSerPort;

						ReadSerReq->io_Baud           = Baud;
						ReadSerReq->io_ReadLen        = DataLen;
						ReadSerReq->io_WriteLen       = DataLen;
						ReadSerReq->io_SerFlags       = (SERF_SHARED|SERF_XDISABLED|SERF_RAD_BOOGIE|(!Cmds->AcLvl[LVL_VARYING_LINK_RATE]*SERF_7WIRE));
						ReadSerReq->io_StopBits       = StopBits;
						ReadSerReq->io_CtlChar        = 0x11130000L;
						ReadSerReq->io_RBufLen        = 16384L;
						ReadSerReq->IOSer.io_Command  = SDCMD_SETPARAMS;
						DoIO(ReadSerReq);
						SerCharSig=1L<<ReadSerPort->mp_SigBit;

						WriteSerReq->IOSer.io_Command = CMD_WRITE;

						ReadSerReq->IOSer.io_Length   = 1;
						ReadSerReq->IOSer.io_Data     = (APTR)serin;
						ReadSerReq->IOSer.io_Command  = CMD_READ;
						SendIO(ReadSerReq);
						SEROUT=1;
						return(FALSE);
						}
                              else
                              {
                                Delay(30L); goto retry;
                              }
					DeleteExtIO(WriteSerReq);
					}
				DeletePort(WriteSerPort);
				}
			DeleteExtIO(ReadSerReq);
			}
		DeletePort(ReadSerPort);
		}
	return(TRUE);
	}
return(FALSE);
}

void LineReset(void);
int CheckCarrier(void)
{
int stat;
int stat2=0;
//char temp[50];
 stat=1;
 if(SEROUT) {
	    WriteSerReq->IOSer.io_Command = SDCMD_QUERY;
 	stat2=DoIO(WriteSerReq);
	    stat = WriteSerReq->io_Status & CIAF_COMCD;
WriteSerReq->IOSer.io_Command = CMD_WRITE;
     if(Sopt->A2232 && !transfering)
     if(WriteSerReq->io_Status && !stat){ LineReset();/* sprintf(temp,"Serial Error %d\n",WriteSerReq->io_Status); ErrorLog(temp);*/}
 	
	}else return(1);
return(stat?FALSE:TRUE);
}

void LineReset(void)
{
  	ReadSerReq->IOSer.io_Command = CMD_RESET;
	    DoIO(ReadSerReq);
 	ReadSerReq->IOSer.io_Command = CMD_READ;
	    SendIO(ReadSerReq);
}
void PurgeLine(void)
{
 if(SEROUT)	{
 	AbortIO(ReadSerReq);
	    WaitIO(ReadSerReq);
 	ReadSerReq->IOSer.io_Command = CMD_CLEAR;
	    DoIO(ReadSerReq);
 	ReadSerReq->IOSer.io_Command = CMD_READ;
	    SendIO(ReadSerReq);
	}
}

void RePurge(void)
{

   while(CheckSer())
   {
     WaitIO(ReadSerReq);
   ReadSerReq->IOSer.io_Command = CMD_READ;
     SendIO(ReadSerReq);
   }
}
void PurgeLineEnd(void)
{
long result;

 if(SEROUT)	{
 	result=CheckIO(ReadSerReq);
	    if(!result)	{
 		AbortIO(ReadSerReq);
		}
	    WaitIO(ReadSerReq);
 	ReadSerReq->IOSer.io_Command = CMD_CLEAR;
	    DoIO(ReadSerReq);
	}
}

void PurgeLineStart(void)
{
 if(SEROUT)	{
 	ReadSerReq->IOSer.io_Command = CMD_CLEAR;
	    DoIO(ReadSerReq);
 	ReadSerReq->IOSer.io_Command = CMD_READ;
	    SendIO(ReadSerReq);
	}
}

extern int Dropped_Hook;
void Reset_System(UBYTE Yes)
{
 extern BOOL TrueReset;
IO_Flags[IOFLAG_KBD_IN]=1;
IO_Flags[IOFLAG_SER_IN]=1;
if(IO_Flags[IOFLAG_FIL_IN])
	{
	IO_Flags[IOFLAG_FIL_IN]=0;
	}
IO_Flags[IOFLAG_SCR_OUT]=0;
IO_Flags[IOFLAG_SER_OUT]=0;
if(Cmds->SerDev[0]!='\0')
{
  
   // if(!Dropped_Hook)
   // {
     PurgeLine();
     DropDTR();
   // }else Dropped_Hook=0;
    Delay(25L);
  if(Cmds->AcLvl[LVL_VARYING_LINK_RATE]==1)
	{
	SetBaud(Cmds->OpeningBaud);
	Delay(25L);
	}
IntDoReset(Cmds->MReset);
if(TrueReset)
	{
     Delay(30L);
	SerPutStr("ATZ\r");
	LineInput("",GSTR3,50,5);
	if(!(strnicmp(GSTR3,"ATZ",3)))
		{
		Delay(50L);//LineInput("",GSTR3,50,5);
		}
	ReInitModem();
	IntDoReset(Cmds->MReset);
	}
 Delay(30L);
 if(Sopt->Toggles[11]) return;
 if(Sopt->Toggles[12]) { RePurge(); return; }
 PurgeLine();
}

}
void IntDoReset(char *s)
{
 UWORD loop;
 register int i;
 i=strlen(s);
 for(loop=0; loop<i; loop++)	{ 
	    if(s[loop]=='~')
 		Delay(110L);
 	else {
 		if(s[loop]=='|'){
 			SerPutStr("\r"); }
 		else
 			SerPutChar(&s[loop]);
		}
	}
 SerPutStr("\r");
 //LineInput("",GSTR3,50,10);
}

void ReInitModem(void)
{
 DropDTR();
 Delay(20L);
 IntDoReset(Sopt->OffHook);
 Delay(60L);
 SerPutStr(Cmds->MInit);
 SerPutStr("\r");
 Delay(60L);
 PurgeLine();
}
void SetBaud(LONG rate)
{
 if(SEROUT)	{
	    PurgeLine();                 /* Flush recieve buffer */
	    AbortIO(ReadSerReq);         /* Abort PurgeLine's read req */
	    WaitIO(ReadSerReq);
	    ReadSerReq->io_Baud = rate;  /* set baud rate */
	    ReadSerReq->IOSer.io_Command = SDCMD_SETPARAMS;
	    DoIO(ReadSerReq);

	    ReadSerReq->IOSer.io_Command = CMD_READ; /* Restart read req */
	    SendIO(ReadSerReq);
	}
}
