home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Da Capo
/
da_capo_vol1.bin
/
programs
/
amiga
/
midi
/
synth_librarian
/
sources
/
synthlib
/
comtask.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-20
|
24KB
|
1,000 lines
/**************************************************************/
/* $VER: ComTask.c Revison 1.1 */
/* This file is part of Synth Librarian v1.1 */
/* ©1993-1994 Jean-Alexis MONTIGNIES */
/* This file must not be distributed modified or separatly */
/* without my written permission */
/* See Synth_Librarian.guide for more details */
/**************************************************************/
/* Synth librarian part for I/O with serial device */
#include <proto/exec.h>
#include <proto/dos.h>
#include <dos/dos.h>
#include <devices/serial.h>
#include <devices/timer.h>
#include <libraries/locale.h>
#include <proto/locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "SynthLib.h"
#define CATCOMP_NUMBERS
#define CATCOMP_BLOCK
#include "ComTaskLoc.h"
struct LocaleInfo CLi;
struct MsgPort *ComPort;
struct IOExtSer *SerialIN,*SerialOUT;
struct timerequest *TimerIO;
ULONG (* DriverPtr)(ULONG *StepPtr,struct Exchange *Ex);
extern struct MsgPort *MainPort;
ULONG Status;
struct Exchange Ex;
ULONG Step;
ULONG MessagePosted;
char FormattedText[64];
BOOL INUsed,OUTUsed,DelayUsed,MessageUsed[2];
struct LibMessage MessTab[2];
STRPTR GetString(struct LocaleInfo *li, LONG stringNum,char *CatCompBlock);
void Request(char *DataPtr,ULONG RemainChars);
void ClearSerial(void);
int ParseINResults( BOOL EOFMode );
void Send(char *DataPtr,ULONG Lenght);
void SendMessage(UBYTE Code,APTR DataPtr);
void ReqDelay(ULONG Duration);
void Advance(void);
ULONG InitComTask(void);
void CloseComTask(void);
void CallDriver(void);
ULONG InitComTask(void)
{ULONG ReturnCode=0;
UBYTE i;
BYTE io_Error=0;
ComPort=NULL;
SerialIN=NULL;
SerialOUT=NULL;
TimerIO=NULL;
DriverPtr=NULL;
MessagePosted=0;
INUsed=OUTUsed=DelayUsed=FALSE;
if(CLi.li_LocaleBase=LocaleBase)
{CLi.li_Catalog=OpenCatalog(NULL,"SynthLib/ComTask.catalog",OC_BuiltInLanguage,"english",TAG_DONE);
}
if (!(ComPort=CreatePort(0,0)))
ReturnCode=CODE_INIT_NOPORT;
for (i=0;i<2;i++)
{MessTab[i].LMess.mn_ReplyPort=ComPort;
MessTab[i].Code=i;
MessageUsed[i]=FALSE;
}
if (!ReturnCode)
if (!(SerialIN=(struct IOExtSer *)CreateExtIO(ComPort,sizeof(struct IOExtSer))))
ReturnCode=CODE_INIT_NOSERIAL;
if (!ReturnCode)
if (OpenDevice(SERIALNAME,0L,(struct IORequest *)SerialIN,0))
{ReturnCode=CODE_INIT_NOSERIAL;
io_Error=SerialIN->IOSer.io_Error;
DeleteExtIO((struct IORequest *)SerialIN);
SerialIN=NULL;
}
if (!ReturnCode)
{
#ifndef DEBUG_SL
SerialIN->io_RBufLen=0x2000;
#else
SerialIN->io_RBufLen=0x20000;
#endif
SerialIN->io_Baud=31250;
SerialIN->io_TermArray.TermArray0=0xFFFEF8F7;
SerialIN->io_TermArray.TermArray1=0xF0F0F0F0;
SerialIN->io_SerFlags|=SERF_RAD_BOOGIE|SERF_EOFMODE|SERF_XDISABLED;
SerialIN->IOSer.io_Command=SDCMD_SETPARAMS;
ReturnCode=DoIO((struct IORequest *)SerialIN);
if (ReturnCode)
ReturnCode=CODE_INIT_NOSERIAL;
}
if (!ReturnCode)
if (SerialOUT=(struct IOExtSer *)CreateExtIO(ComPort,sizeof(struct IOExtSer)))
{memcpy(SerialOUT,SerialIN,sizeof(struct IOExtSer));
SerialOUT->io_SerFlags&=~SERF_EOFMODE;
}
else
{
ReturnCode=CODE_INIT_NOSERIAL;
io_Error=SerialOUT->IOSer.io_Error;
}
if (!ReturnCode)
if (!(TimerIO=(struct timerequest *)CreateExtIO(ComPort,sizeof(struct timerequest))))
ReturnCode=CODE_INIT_NOTIMER;
if (!ReturnCode)
if (OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)TimerIO,0))
{ReturnCode=CODE_INIT_NOTIMER;
DeleteExtIO((struct IORequest *)TimerIO);
TimerIO=NULL;
}
if (!ReturnCode)
SendMessage(MSGCODE_INFO,GetString(&CLi,ReturnCode,ComCatBlock));
if (ReturnCode)
if (ReturnCode==CODE_INIT_NOSERIAL && (io_Error>0))
SendMessage(MSGCODE_ERROR,GetString(&CLi,MSG_SERIAL-1+SerialIN->IOSer.io_Error,ComCatBlock));
else
SendMessage(MSGCODE_ERROR,GetString(&CLi,MSG_INIT-1+ReturnCode,ComCatBlock));
return(ReturnCode);
}
void CloseComTask()
{struct Message *Mess;
if (DriverPtr)
{Step=STEP_EXIT_DRIVER;
DriverPtr(&Step,&Ex);
}
if (TimerIO && DelayUsed)
AbortIO((struct IORequest *)TimerIO);
if (SerialOUT && OUTUsed)
AbortIO((struct IORequest *)SerialOUT);
if (SerialIN && INUsed)
AbortIO((struct IORequest *)SerialIN);
if (ComPort)
{do
{while(Mess=GetMsg(ComPort))
if (Mess->mn_ReplyPort!=ComPort)
{if (Mess->mn_ReplyPort==MainPort)
((struct LibMessage *)Mess)->Code|=MSGCODE_IGNORED;
ReplyMsg(Mess);
}
else
{MessagePosted--;
if (Mess!=SerialIN && Mess!=SerialOUT)
if (((struct LibMessage *)Mess)->Code>=2)
FreeMem((APTR)Mess,sizeof(struct LibMessage));
}
if (MessagePosted)
Wait(1<<(ComPort->mp_SigBit));
}
while(MessagePosted);
}
if (TimerIO)
{CloseDevice((struct IORequest *)TimerIO);
DeleteExtIO((struct IORequest *)TimerIO);
}
if (SerialIN)
{CloseDevice((struct IORequest *)SerialIN);
DeleteExtIO((struct IORequest *)SerialIN);
}
if (SerialOUT)
DeleteExtIO((struct IORequest *)SerialOUT);
MessTab[0].LMess.mn_ReplyPort=NULL;
MessTab[0].Code=MSGCODE_BYE;
MessTab[0].Data=GetString(&CLi,MSG_BYE,ComCatBlock);
PutMsg(MainPort,(struct Message *)&MessTab[0]);
if (LocaleBase)
{CloseCatalog(CLi.li_Catalog);
}
Wait(SIGBREAKF_CTRL_C);
if (ComPort)
{while(Mess=GetMsg(ComPort))
{if (Mess->mn_ReplyPort==MainPort)
((struct LibMessage *)Mess)->Code|=MSGCODE_IGNORED;
ReplyMsg(Mess);
}
DeletePort(ComPort);
}
}
void Request(char *DataPtr,ULONG RemainChars)
{
SerialIN->IOSer.io_Command=CMD_READ;
SerialIN->IOSer.io_Length=min(RemainChars,128);
SerialIN->IOSer.io_Data=(APTR)DataPtr;
SerialIN->IOSer.io_Flags|=IOF_QUICK;
BeginIO((struct IORequest *)SerialIN);
if (!(SerialIN->IOSer.io_Flags & IOF_QUICK))
{MessagePosted++;
INUsed=TRUE;
}
}
void Send(char *DataPtr,ULONG Length)
{SerialOUT->IOSer.io_Command=CMD_WRITE;
SerialOUT->IOSer.io_Length=Length;
SerialOUT->IOSer.io_Data=(APTR)DataPtr;
SerialOUT->IOSer.io_Flags|=IOF_QUICK;
BeginIO((struct IORequest *)SerialOUT);
if (!(SerialOUT->IOSer.io_Flags & IOF_QUICK))
{MessagePosted++;
OUTUsed=TRUE;
}
}
void ClearSerial()
{SerialIN->IOSer.io_Command=CMD_CLEAR;
SerialIN->IOSer.io_Flags|=IOF_QUICK;
BeginIO((struct IORequest *)SerialIN);
if (!(SerialIN->IOSer.io_Flags & IOF_QUICK))
{MessagePosted++;
INUsed=TRUE;
}
}
void SendMessage(UBYTE Code,APTR DataPtr)
{struct LibMessage *Mess;
if (Code>=2)
{ /* Message très important */
Mess=(struct LibMessage *)AllocMem(sizeof(struct LibMessage),0L);
if (Mess)
{Mess->LMess.mn_Length=sizeof(struct LibMessage);
Mess->LMess.mn_ReplyPort=ComPort;
Mess->Code=Code;
Mess->Data=DataPtr;
PutMsg(MainPort,(struct Message *)Mess);
MessagePosted++;
}
else
/* Cas désespéré, on efface les données recues */
{
if (Code==MSGCODE_DATA || (Code==MSGCODE_REQ_RESULT && DataPtr))
{
FreeMem(((struct DumpNode *)DataPtr)->Dump,((struct DumpNode *)DataPtr)->DumpLength);
if (((struct DumpNode *)DataPtr)->Data)
FreeMem(((struct DumpNode *)DataPtr)->Data,((struct DumpNode *)DataPtr)->DataLength);
FreeMem(DataPtr,sizeof(struct DumpNode));
}
}
}
else
/* Message moins important */
if (!MessageUsed[Code])
{MessageUsed[Code]=TRUE;
MessTab[Code].Data=DataPtr;
PutMsg(MainPort,(struct Message *)(&MessTab[Code]));
MessagePosted++;
}
}
void ReqDelay(ULONG Duration)
{ if (DelayUsed)
{AbortIO((struct IORequest *)TimerIO);
WaitIO((struct IORequest *)TimerIO);
MessagePosted--;
}
TimerIO->tr_node.io_Command=TR_ADDREQUEST;
TimerIO->tr_time.tv_secs=Duration/1000000;
TimerIO->tr_time.tv_micro=Duration%1000000;
SendIO((struct IORequest *)TimerIO