home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Sound / MidI / SYNTHLIB.LHA / Synth_Librarian / sources / SynthLib / ComTask.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-20  |  23.1 KB  |  1,000 lines

  1. /**************************************************************/
  2. /* $VER: ComTask.c Revison 1.1                                */
  3. /* This file is part of Synth Librarian v1.1                  */
  4. /* ©1993-1994 Jean-Alexis MONTIGNIES                          */
  5. /* This file must not be distributed modified or separatly    */
  6. /* without my written permission                              */
  7. /* See Synth_Librarian.guide for more details                 */
  8. /**************************************************************/
  9. /* Synth librarian part for I/O with serial device */
  10. #include <proto/exec.h>
  11. #include <proto/dos.h>
  12. #include <dos/dos.h>
  13. #include <devices/serial.h>
  14. #include <devices/timer.h>
  15. #include <libraries/locale.h>
  16. #include <proto/locale.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <math.h>
  20. #include <string.h>
  21. #include "SynthLib.h"
  22. #define CATCOMP_NUMBERS
  23. #define CATCOMP_BLOCK
  24. #include "ComTaskLoc.h"
  25.  
  26. struct LocaleInfo CLi;
  27. struct MsgPort *ComPort;
  28. struct IOExtSer *SerialIN,*SerialOUT;
  29. struct timerequest *TimerIO;
  30. ULONG (* DriverPtr)(ULONG *StepPtr,struct Exchange *Ex);
  31. extern struct MsgPort *MainPort;
  32.  
  33. ULONG Status;
  34. struct Exchange Ex;
  35. ULONG Step;
  36. ULONG MessagePosted;
  37. char FormattedText[64];
  38. BOOL INUsed,OUTUsed,DelayUsed,MessageUsed[2];
  39. struct LibMessage MessTab[2];
  40.  
  41. STRPTR GetString(struct LocaleInfo *li, LONG stringNum,char *CatCompBlock);
  42. void Request(char *DataPtr,ULONG RemainChars);
  43. void ClearSerial(void);
  44. int ParseINResults( BOOL EOFMode );
  45. void Send(char *DataPtr,ULONG Lenght);
  46. void SendMessage(UBYTE Code,APTR DataPtr);
  47. void ReqDelay(ULONG Duration);
  48. void Advance(void);
  49. ULONG InitComTask(void);
  50. void CloseComTask(void);
  51. void CallDriver(void);
  52.  
  53. ULONG InitComTask(void)
  54.  {ULONG ReturnCode=0;
  55.   UBYTE i;
  56.   BYTE io_Error=0;
  57.  
  58.   ComPort=NULL;
  59.   SerialIN=NULL;
  60.   SerialOUT=NULL;
  61.   TimerIO=NULL;
  62.   DriverPtr=NULL;
  63.   MessagePosted=0;
  64.   INUsed=OUTUsed=DelayUsed=FALSE;
  65.  
  66.   if(CLi.li_LocaleBase=LocaleBase)
  67.    {CLi.li_Catalog=OpenCatalog(NULL,"SynthLib/ComTask.catalog",OC_BuiltInLanguage,"english",TAG_DONE);
  68.    }
  69.   if (!(ComPort=CreatePort(0,0)))
  70.     ReturnCode=CODE_INIT_NOPORT;
  71.  
  72.   for (i=0;i<2;i++)
  73.    {MessTab[i].LMess.mn_ReplyPort=ComPort;
  74.     MessTab[i].Code=i;
  75.     MessageUsed[i]=FALSE;
  76.    }
  77.  
  78.   if (!ReturnCode)
  79.     if (!(SerialIN=(struct IOExtSer *)CreateExtIO(ComPort,sizeof(struct IOExtSer))))
  80.       ReturnCode=CODE_INIT_NOSERIAL;
  81.  
  82.   if (!ReturnCode)
  83.     if (OpenDevice(SERIALNAME,0L,(struct IORequest *)SerialIN,0))
  84.      {ReturnCode=CODE_INIT_NOSERIAL;
  85.       io_Error=SerialIN->IOSer.io_Error;
  86.       DeleteExtIO((struct IORequest *)SerialIN);
  87.       SerialIN=NULL;
  88.      }
  89.  
  90.   if (!ReturnCode)
  91.    {
  92. #ifndef DEBUG_SL
  93.     SerialIN->io_RBufLen=0x2000;
  94. #else
  95.     SerialIN->io_RBufLen=0x20000;
  96. #endif
  97.     SerialIN->io_Baud=31250;
  98.     SerialIN->io_TermArray.TermArray0=0xFFFEF8F7;
  99.     SerialIN->io_TermArray.TermArray1=0xF0F0F0F0;
  100.     SerialIN->io_SerFlags|=SERF_RAD_BOOGIE|SERF_EOFMODE|SERF_XDISABLED;
  101.     SerialIN->IOSer.io_Command=SDCMD_SETPARAMS;
  102.     ReturnCode=DoIO((struct IORequest *)SerialIN);
  103.     if (ReturnCode)
  104.       ReturnCode=CODE_INIT_NOSERIAL;
  105.    }
  106.  
  107.   if (!ReturnCode)
  108.     if (SerialOUT=(struct IOExtSer *)CreateExtIO(ComPort,sizeof(struct IOExtSer)))
  109.      {memcpy(SerialOUT,SerialIN,sizeof(struct IOExtSer));
  110.       SerialOUT->io_SerFlags&=~SERF_EOFMODE;
  111.      }
  112.      else
  113.      {
  114.       ReturnCode=CODE_INIT_NOSERIAL;
  115.       io_Error=SerialOUT->IOSer.io_Error;
  116.      }
  117.  
  118.   if (!ReturnCode)
  119.     if (!(TimerIO=(struct timerequest *)CreateExtIO(ComPort,sizeof(struct timerequest))))
  120.       ReturnCode=CODE_INIT_NOTIMER;
  121.  
  122.   if (!ReturnCode)
  123.     if (OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)TimerIO,0))
  124.      {ReturnCode=CODE_INIT_NOTIMER;
  125.       DeleteExtIO((struct IORequest *)TimerIO);
  126.       TimerIO=NULL;
  127.      }
  128.  
  129.   if (!ReturnCode)
  130.       SendMessage(MSGCODE_INFO,GetString(&CLi,ReturnCode,ComCatBlock));
  131.  
  132.   if (ReturnCode)
  133.     if (ReturnCode==CODE_INIT_NOSERIAL && (io_Error>0))
  134.       SendMessage(MSGCODE_ERROR,GetString(&CLi,MSG_SERIAL-1+SerialIN->IOSer.io_Error,ComCatBlock));
  135.      else
  136.       SendMessage(MSGCODE_ERROR,GetString(&CLi,MSG_INIT-1+ReturnCode,ComCatBlock));
  137.  
  138.   return(ReturnCode);
  139.  }
  140.  
  141. void CloseComTask()
  142.  {struct Message *Mess;
  143.  
  144.   if (DriverPtr)
  145.    {Step=STEP_EXIT_DRIVER;
  146.     DriverPtr(&Step,&Ex);
  147.    }
  148.  
  149.   if (TimerIO && DelayUsed)
  150.     AbortIO((struct IORequest *)TimerIO);
  151.  
  152.   if (SerialOUT && OUTUsed)
  153.     AbortIO((struct IORequest *)SerialOUT);
  154.  
  155.   if (SerialIN && INUsed)
  156.     AbortIO((struct IORequest *)SerialIN);
  157.  
  158.   if (ComPort)
  159.    {do
  160.      {while(Mess=GetMsg(ComPort))
  161.         if (Mess->mn_ReplyPort!=ComPort)
  162.          {if (Mess->mn_ReplyPort==MainPort)
  163.             ((struct LibMessage *)Mess)->Code|=MSGCODE_IGNORED;
  164.           ReplyMsg(Mess);
  165.          }
  166.          else
  167.          {MessagePosted--;
  168.           if (Mess!=SerialIN && Mess!=SerialOUT)
  169.             if (((struct LibMessage *)Mess)->Code>=2)
  170.               FreeMem((APTR)Mess,sizeof(struct LibMessage));
  171.          }
  172.       if (MessagePosted)
  173.         Wait(1<<(ComPort->mp_SigBit));
  174.      }
  175.     while(MessagePosted);
  176.    }
  177.  
  178.   if (TimerIO)
  179.    {CloseDevice((struct IORequest *)TimerIO);
  180.     DeleteExtIO((struct IORequest *)TimerIO);
  181.    }
  182.  
  183.   if (SerialIN)
  184.    {CloseDevice((struct IORequest *)SerialIN);
  185.     DeleteExtIO((struct IORequest *)SerialIN);
  186.    }
  187.  
  188.   if (SerialOUT)
  189.     DeleteExtIO((struct IORequest *)SerialOUT);
  190.  
  191.   MessTab[0].LMess.mn_ReplyPort=NULL;
  192.   MessTab[0].Code=MSGCODE_BYE;
  193.   MessTab[0].Data=GetString(&CLi,MSG_BYE,ComCatBlock);
  194.   PutMsg(MainPort,(struct Message *)&MessTab[0]);
  195.  
  196.   if (LocaleBase)
  197.    {CloseCatalog(CLi.li_Catalog);
  198.    }
  199.  
  200.   Wait(SIGBREAKF_CTRL_C);
  201.  
  202.   if (ComPort)
  203.    {while(Mess=GetMsg(ComPort))
  204.      {if (Mess->mn_ReplyPort==MainPort)
  205.         ((struct LibMessage *)Mess)->Code|=MSGCODE_IGNORED;
  206.       ReplyMsg(Mess);
  207.      }
  208.  
  209.     DeletePort(ComPort);
  210.    }
  211.  }
  212.  
  213. void Request(char *DataPtr,ULONG RemainChars)
  214.  {
  215.   SerialIN->IOSer.io_Command=CMD_READ;
  216.   SerialIN->IOSer.io_Length=min(RemainChars,128);
  217.   SerialIN->IOSer.io_Data=(APTR)DataPtr;
  218.   SerialIN->IOSer.io_Flags|=IOF_QUICK;
  219.   BeginIO((struct IORequest *)SerialIN);
  220.  
  221.   if (!(SerialIN->IOSer.io_Flags & IOF_QUICK))
  222.    {MessagePosted++;
  223.     INUsed=TRUE;
  224.    }
  225.  }
  226.  
  227. void Send(char *DataPtr,ULONG Length)
  228.  {SerialOUT->IOSer.io_Command=CMD_WRITE;
  229.   SerialOUT->IOSer.io_Length=Length;
  230.   SerialOUT->IOSer.io_Data=(APTR)DataPtr;
  231.   SerialOUT->IOSer.io_Flags|=IOF_QUICK;
  232.   BeginIO((struct IORequest *)SerialOUT);
  233.  
  234.   if (!(SerialOUT->IOSer.io_Flags & IOF_QUICK))
  235.    {MessagePosted++;
  236.     OUTUsed=TRUE;
  237.    }
  238.  }
  239.  
  240. void ClearSerial()
  241.  {SerialIN->IOSer.io_Command=CMD_CLEAR;
  242.   SerialIN->IOSer.io_Flags|=IOF_QUICK;
  243.   BeginIO((struct IORequest *)SerialIN);
  244.  
  245.   if (!(SerialIN->IOSer.io_Flags & IOF_QUICK))
  246.    {MessagePosted++;
  247.     INUsed=TRUE;
  248.    }
  249.  }
  250.  
  251. void SendMessage(UBYTE Code,APTR DataPtr)
  252.  {struct LibMessage *Mess;
  253.  
  254.   if (Code>=2)
  255.    { /* Message très important */
  256.     Mess=(struct LibMessage *)AllocMem(sizeof(struct LibMessage),0L);
  257.     if (Mess)
  258.      {Mess->LMess.mn_Length=sizeof(struct LibMessage);
  259.       Mess->LMess.mn_ReplyPort=ComPort;
  260.       Mess->Code=Code;
  261.       Mess->Data=DataPtr;
  262.  
  263.       PutMsg(MainPort,(struct Message *)Mess);
  264.       MessagePosted++;
  265.      }
  266.      else
  267.      /* Cas désespéré, on efface les données recues */
  268.      {
  269.       if (Code==MSGCODE_DATA || (Code==MSGCODE_REQ_RESULT && DataPtr))
  270.        {
  271.         FreeMem(((struct DumpNode *)DataPtr)->Dump,((struct DumpNode *)DataPtr)->DumpLength);
  272.         if (((struct DumpNode *)DataPtr)->Data)
  273.           FreeMem(((struct DumpNode *)DataPtr)->Data,((struct DumpNode *)DataPtr)->DataLength);
  274.         FreeMem(DataPtr,sizeof(struct DumpNode));
  275.        }
  276.      }
  277.    }
  278.    else
  279.      /* Message moins important */
  280.     if (!MessageUsed[Code])
  281.      {MessageUsed[Code]=TRUE;
  282.       MessTab[Code].Data=DataPtr;
  283.  
  284.       PutMsg(MainPort,(struct Message *)(&MessTab[Code]));
  285.       MessagePosted++;
  286.      }
  287.  }
  288.  
  289. void ReqDelay(ULONG Duration)
  290.  { if (DelayUsed)
  291.     {AbortIO((struct IORequest *)TimerIO);
  292.      WaitIO((struct IORequest *)TimerIO);
  293.      MessagePosted--;
  294.     }
  295.  
  296.    TimerIO->tr_node.io_Command=TR_ADDREQUEST;
  297.    TimerIO->tr_time.tv_secs=Duration/1000000;
  298.    TimerIO->tr_time.tv_micro=Duration%1000000;
  299.    SendIO((struct IORequest *)TimerIO);
  300.  
  301.    DelayUsed=TRUE;
  302.    MessagePosted++;
  303.  
  304.  }
  305.  
  306. void CallDriver()
  307.  {int Error=0;
  308.  
  309.   Ex.Message=NULL;
  310.  
  311.   Error=DriverPtr(&Step,&Ex);
  312.   if (Error)
  313.     SendMessage(MSGCODE_ERROR,Ex.Message);
  314.  
  315.   if (Ex.Message)
  316.     SendMessage(MSGCODE_INFO,Ex.Message);
  317.  }
  318.  
  319. int ParseINResults(BOOL EOFMode)
  320.  {int ReturnCode=0;
  321.   BOOL EofReached;
  322.  
  323.   if (SerialIN->IOSer.io_Error)
  324.     ReturnCode=3;
  325.    else
  326.    {Ex.Length-=SerialIN->IOSer.io_Actual;
  327.     Ex.DataPtr+=SerialIN->IOSer.io_Actual;
  328.  
  329.     EofReached=(Ex.DataPtr[-1]==(Ex.Data1 & 0xFF))||(Ex.DataPtr[-1]==((Ex.Data1>>8)& 0xFF))\
  330.              ||(Ex.DataPtr[-1]==((Ex.Data1>>16) & 0xFF))||(Ex.DataPtr[-1]==(Ex.Data1>>24));
  331.     if (!(EofReached && EOFMode))
  332.       if (Ex.DataPtr[-1]==0xF8 || Ex.DataPtr[-1]==0xFE)
  333.        {Ex.Length++;
  334.         Ex.DataPtr--;
  335.         ReturnCode=1;
  336.        }
  337.        else
  338.          if (Ex.DataPtr[-1]>0x7F)
  339.            ReturnCode=2;
  340.           else
  341.            if (Ex.Length)
  342.              ReturnCode=1;
  343.    }
  344.   return(ReturnCode);
  345.  }
  346.  
  347. void Advance(void)
  348.  {static unsigned char TempBuffer[0x80];
  349.   int Error=0;
  350.  
  351.   switch(Step)
  352.    {
  353. /************************************************************/
  354. /*                        Réception                         */
  355. /************************************************************/
  356.     case STEP_RECIEVE_COMPLETE:
  357.       SendMessage(MSGCODE_DATA,Ex.Node);
  358.       Step=STEP_WAIT;
  359.       Status&=~STATUS_RECIEVING;
  360.  
  361.       break;
  362.  
  363.     case STEP_ABORT:     /* Annulation */
  364.       if (INUsed)
  365.         AbortIO((struct IORequest *)SerialIN);
  366.  
  367.       CallDriver();
  368.       Step=STEP_WAIT;
  369.  
  370.       Status&=~STATUS_RECIEVING;
  371.       Status|=STATUS_WAIT_IN;
  372.  
  373.       break;
  374.  
  375.     case STEP_IO_ERROR:     /* En cas d'erreur */
  376.       SendMessage(MSGCODE_ERROR,GetString(&CLi,MSG_SERIAL-1+SerialIN->IOSer.io_Error,ComCatBlock));
  377.       ClearSerial();
  378.  
  379.       if (Status & STATUS_RECIEVING)
  380.        {Step=STEP_ABORT;
  381.         CallDriver();
  382.        }
  383.  
  384.       Step=STEP_WAIT;
  385.       Status=(Status&~STATUS_RECIEVING)|STATUS_WAIT_IN;
  386.  
  387.       break;
  388.  
  389.     case STEP_WAIT:      /* Attente */
  390.     
  391.     Status&=~STATUS_RECIEVING;
  392.     
  393.     case STEP_NEXT_SYSEX:
  394.       if (INUsed)
  395.         Status|=STATUS_WAIT_IN;
  396.        else
  397.        {
  398.         Step++;
  399.  
  400.         Request(TempBuffer,0x80);
  401.         Status|=STATUS_WAIT_IN;
  402.        }
  403.  
  404.       break;
  405.  
  406.     case STEP_NEXT_SYSEX+1:
  407.     case STEP_START:     /* Attente d'un début de message exclusif */
  408.       if (SerialIN->IOSer.io_Error)
  409.         Step=STEP_IO_ERROR;
  410.        else
  411.         if ((TempBuffer[SerialIN->IOSer.io_Actual-1]==0xF0) && DriverPtr)
  412.          {Ex.Length=0;
  413.           if (Step!=STEP_START)
  414.             Step=STEP_CONTINUE;
  415.            else
  416.             Status|=STATUS_RECIEVING;
  417.           CallDriver();
  418.          }
  419.          else
  420.           Step--;
  421.           
  422.        break;
  423.  
  424.     case STEP_RECIEVE:
  425.       Request(Ex.DataPtr,Ex.Length);
  426.       Step=STEP_CONTINUE;
  427.       Status|=STATUS_WAIT_IN;
  428.  
  429.       break;
  430.  
  431.     case STEP_CONTINUE:
  432.       switch(ParseINResults(0))
  433.        {case 0:
  434.           CallDriver();
  435.  
  436.           break;
  437.  
  438.         case 1:
  439.           Step=STEP_RECIEVE;
  440.  
  441.           break;
  442.  
  443.         case 2:
  444.           SendMessage(1,GetString(&CLi,MSG_UNEXPECTED,ComCatBlock));
  445.           Step=STEP_ABORT;
  446.  
  447.           break;
  448.  
  449.         case 3:
  450.           Step=STEP_IO_ERROR;
  451.  
  452.           break;
  453.        }
  454.  
  455.       break;
  456.  
  457.     case STEP_RECIEVE_EOF:
  458.       Request(Ex.DataPtr,Ex.Length);
  459.       Step=5;
  460.       Status|=STATUS_WAIT_IN;
  461.  
  462.       break;
  463.  
  464.     case 5:
  465.       switch(ParseINResults(1))
  466.        {case 0:
  467.           Step=STEP_CONTINUE;
  468.           CallDriver();
  469.  
  470.           break;
  471.  
  472.         case 1:
  473.           Step=STEP_RECIEVE_EOF;
  474.  
  475.           break;
  476.  
  477.         case 2:
  478.           SendMessage(1,GetString(&CLi,MSG_UNEXPECTED,ComCatBlock));
  479.           Step=STEP_ABORT;
  480.  
  481.           break;
  482.  
  483.         case 3:
  484.           Step=STEP_IO_ERROR;
  485.  
  486.           break;
  487.        }
  488.  
  489.       break;
  490.  
  491. /************************************************************/
  492. /*                        Emission                          */
  493. /************************************************************/
  494.  
  495.     case STEP_SEND_COMPLETE:
  496.       SendMessage(MSGCODE_SEND_FINISHED,Ex.Node);
  497.  
  498.       Status&=~STATUS_SENDING;
  499.       Step=STEP_WAIT;
  500.  
  501.       break;
  502.  
  503.     case STEP_SEND_ABORT:
  504.       CallDriver();
  505.  
  506.       SendMessage(MSGCODE_SEND_FINISHED,Ex.Node);
  507.  
  508.       if (OUTUsed)
  509.         AbortIO((struct IORequest *)SerialOUT);
  510.  
  511.       if (DelayUsed)
  512.         AbortIO((struct IORequest *)TimerIO);
  513.  
  514.       if (INUsed)
  515.         AbortIO((struct IORequest *)SerialIN);
  516.  
  517.       Status&=~(STATUS_SENDING+STATUS_MASK_WAIT);
  518.       Status|=STATUS_WAIT_ALL;
  519.       Step=STEP_WAIT;
  520.  
  521.       break;
  522.  
  523.     case STEP_SEND_START:
  524.     case STEP_SEND_CONTINUE:
  525.       CallDriver();
  526.  
  527.       break;
  528.  
  529.     case STEP_SEND_SEND:
  530.       Step=STEP_SEND+4;
  531.  
  532.       Status|=STATUS_WAIT_OUT;
  533.       break;
  534.  
  535.     case STEP_SEND+4:
  536.       if (SerialOUT->IOSer.io_Error)
  537.         Step=STEP_SEND_ABORT;
  538.        else
  539.        {Send(Ex.DataPtr,Ex.Length);
  540.         Step=STEP_SEND_CONTINUE;
  541.         CallDriver();
  542.        }
  543.  
  544.       break;
  545.  
  546.     case STEP_SEND_DELAY:
  547.       ReqDelay(Ex.Data1);
  548.       Status|=STATUS_WAIT_DELAY;
  549.  
  550.       Step=STEP_SEND_CONTINUE;
  551.  
  552.       break;
  553.  
  554.     case STEP_SEND_IO_ERROR:     /* En cas d'erreur */
  555.       SendMessage(MSGCODE_ERROR,GetString(&CLi,MSG_SERIAL-1+SerialIN->IOSer.io_Error,ComCatBlock));
  556.       ClearSerial();
  557.  
  558.       Step=STEP_SEND_ABORT;
  559.       
  560.       Status=STATUS_WAIT_IN;
  561.  
  562.       break;
  563.  
  564.     case STEP_SEND_WAIT:      /* Attente */
  565.       if (INUsed)
  566.         Status|=STATUS_WAIT_IN;
  567.        else
  568.        {
  569.         Step=STEP_SEND+7;
  570.  
  571.         Request(TempBuffer,0x80);
  572.         Status|=STATUS_WAIT_IN;
  573.        }
  574.  
  575.       break;
  576.  
  577.     case STEP_SEND+7:     /* Attente d'un début de message exclusif */
  578.       if (SerialIN->IOSer.io_Error)
  579.         Step=STEP_SEND_IO_ERROR;
  580.        else
  581.         if ((TempBuffer[SerialIN->IOSer.io_Actual-1]==0xF0) && DriverPtr)
  582.          {Ex.Length=0;
  583.           Step=STEP_SEND_CONTINUE;
  584.           CallDriver();
  585.          }
  586.          else
  587.           Step=STEP_SEND_WAIT;
  588.  
  589.       break;
  590.  
  591.     case STEP_SEND_RECIEVE:
  592.       Request(Ex.DataPtr,Ex.Length);
  593.       Step=STEP_SEND+9;
  594.       Status|=STATUS_WAIT_IN;
  595.  
  596.       break;
  597.  
  598.     case STEP_SEND+9:
  599.       switch(ParseINResults(0))
  600.        {case 0:
  601.           Step=STEP_SEND_CONTINUE;
  602.           CallDriver();
  603.  
  604.           break;
  605.  
  606.         case 1:
  607.           Step=STEP_SEND_RECIEVE;
  608.  
  609.           break;
  610.  
  611.         case 2:
  612.           SendMessage(1,GetString(&CLi,MSG_UNEXPECTED,ComCatBlock));
  613.           Step=STEP_SEND_ABORT;
  614.  
  615.           break;
  616.  
  617.         case 3:
  618.           Step=STEP_SEND_IO_ERROR;
  619.  
  620.           break;
  621.        }
  622.  
  623.       break;
  624.  
  625.     case STEP_SEND_RECIEVE_EOF:
  626.       Request(Ex.DataPtr,Ex.Length);
  627.       Step=STEP_SEND+11;
  628.       Status|=STATUS_WAIT_IN;
  629.  
  630.       break;
  631.  
  632.     case STEP_SEND+11:
  633.       switch(ParseINResults(1))
  634.        {case 0:
  635.           Step=STEP_SEND_CONTINUE;
  636.           CallDriver();
  637.  
  638.           break;
  639.  
  640.         case 1:
  641.           Step=STEP_SEND_RECIEVE_EOF;
  642.  
  643.           break;
  644.  
  645.         case 2:
  646.           SendMessage(1,GetString(&CLi,MSG_UNEXPECTED,ComCatBlock));
  647.           Step=STEP_SEND_ABORT;
  648.  
  649.           break;
  650.  
  651.         case 3:
  652.           Step=STEP_SEND_IO_ERROR;
  653.  
  654.           break;
  655.        }
  656.  
  657.       break;
  658.  
  659. /************************************************************/
  660. /*                        Requette                          */
  661. /************************************************************/
  662.  
  663.     case STEP_REQ_ABORT:     /* Annulation */
  664.       if (INUsed)
  665.         AbortIO((struct IORequest *)SerialIN);
  666.  
  667.       if (OUTUsed)
  668.         AbortIO((struct IORequest *)SerialOUT);
  669.  
  670.       CallDriver();
  671.       Step=STEP_WAIT;
  672.  
  673.       Ex.Node=NULL;
  674.       SendMessage(MSGCODE_REQ_RESULT,Ex.Node);
  675.  
  676.       Status&=~STATUS_REQUEST;
  677.       Status|=STATUS_WAIT_IN;
  678.  
  679.       break;
  680.  
  681.     case STEP_REQ_IO_ERROR:     /* En cas d'erreur */
  682.  
  683.       SendMessage(MSGCODE_ERROR,GetString(&CLi,MSG_SERIAL+SerialIN->IOSer.io_Error-1,ComCatBlock));
  684.       ClearSerial();
  685.  
  686.       Step=STEP_REQ_ABORT;
  687.       CallDriver();
  688.  
  689.       Ex.Node=0;
  690.       SendMessage(MSGCODE_REQ_RESULT,Ex.Node);
  691.  
  692.       Step=STEP_WAIT;
  693.       Status=(Status&~STATUS_REQUEST)|STATUS_WAIT_IN;
  694.  
  695.       break;
  696.  
  697.     case STEP_REQ_WAIT:      /* Attente */
  698.       if (INUsed)
  699.         Status|=STATUS_WAIT_IN;
  700.        else
  701.        {
  702.         Step=STEP_REQ+5;
  703.  
  704.         Request(TempBuffer,0x80);
  705.         Status|=STATUS_WAIT_IN;
  706.        }
  707.  
  708.       break;
  709.  
  710.     case STEP_REQ+5:     /* Attente d'un début de message exclusif */
  711.       if (SerialIN->IOSer.io_Error)
  712.         Step=STEP_REQ_IO_ERROR;
  713.        else
  714.         if (TempBuffer[SerialIN->IOSer.io_Actual-1]==0xF0)
  715.          {Ex.Length=0;
  716.           Step=STEP_REQ_CONTINUE;
  717.           CallDriver();
  718.          }
  719.          else
  720.           Step=STEP_REQ_WAIT;
  721.  
  722.       break;
  723.  
  724.     case STEP_REQ_RECIEVE:
  725.       Request(Ex.DataPtr,Ex.Length);
  726.       Step=STEP_REQ_CONTINUE;
  727.       Status|=STATUS_WAIT_IN;
  728.  
  729.       break;
  730.  
  731.     case STEP_REQ_CONTINUE:
  732.           switch(ParseINResults(0))
  733.        {case 0:
  734.           CallDriver();
  735.  
  736.           break;
  737.  
  738.         case 1:
  739.           Step=STEP_REQ_RECIEVE;
  740.  
  741.           break;
  742.  
  743.         case 2:
  744.           SendMessage(1,GetString(&CLi,MSG_UNEXPECTED,ComCatBlock));
  745.           Step=STEP_REQ_ABORT;
  746.  
  747.           break;
  748.  
  749.         case 3:
  750.           Step=STEP_REQ_IO_ERROR;
  751.  
  752.           break;
  753.        }
  754.  
  755.        break;
  756.  
  757.     case STEP_REQ_RECIEVE_EOF:
  758.       Request(Ex.DataPtr,Ex.Length);
  759.       Step=STEP_REQ+9;
  760.       Status|=STATUS_WAIT_IN;
  761.  
  762.       break;
  763.  
  764.     case STEP_REQ+9:
  765.       switch(ParseINResults(1))
  766.        {case 0:
  767.           Step=STEP_REQ_CONTINUE;
  768.           CallDriver();
  769.  
  770.           break;
  771.  
  772.         case 1:
  773.           Step=STEP_REQ_RECIEVE_EOF;
  774.  
  775.           break;
  776.  
  777.         case 2:
  778.           SendMessage(1,GetString(&CLi,MSG_UNEXPECTED,ComCatBlock));
  779.           Step=STEP_REQ_ABORT;
  780.  
  781.           break;
  782.  
  783.         case 3:
  784.           Step=STEP_REQ_IO_ERROR;
  785.  
  786.           break;
  787.        }
  788.  
  789.       break;
  790.  
  791.     case STEP_REQ_COMPLETE:
  792.       SendMessage(MSGCODE_REQ_RESULT,Ex.Node);
  793.  
  794.       Status&=~STATUS_REQUEST;
  795.       Step=STEP_WAIT;
  796.  
  797.       break;
  798.  
  799.     case STEP_REQ_START:
  800.       if (INUsed)
  801.         AbortIO((struct IORequest *)SerialIN);
  802.       CallDriver();
  803.  
  804.       break;
  805.  
  806.     case STEP_REQ_SEND:
  807.       Step=STEP_REQ+2;
  808.  
  809.       Status|=STATUS_WAIT_OUT_IN;
  810.       break;
  811.  
  812.     case STEP_REQ+2:
  813.       if (SerialOUT->IOSer.io_Error)
  814.         Step=STEP_REQ_ABORT;
  815.        else
  816.        {Send(Ex.DataPtr,Ex.Length);
  817.         Step=STEP_REQ_CONTINUE;
  818.         CallDriver();
  819.        }
  820.  
  821.       break;
  822.    }
  823.  }
  824.  
  825. void __saveds ComTask()
  826.  {
  827.   BOOL HTWait;
  828.   ULONG MessMask,Signals;
  829.   struct Message *Mess;
  830.   int Error;
  831.   UBYTE Code;
  832.   UBYTE *DataPtr;
  833.   Status=0;
  834.   Error=0;
  835.  
  836.   Error=InitComTask();
  837.   Step=STEP_WAIT;
  838.  
  839.   if (!Error)
  840.    {
  841.     MessMask= 1<<(ComPort->mp_SigBit);
  842.  
  843.     while (!((Status & STATUS_EXIT)&& !(Status & STATUS_NOEXIT)))
  844.      {
  845.       if ((Status & STATUS_QUIT_DRIVER) && !(Status & STATUS_NOEXIT) && DriverPtr)
  846.        {ULONG Step2;
  847.  
  848.         Step2=Step;
  849.         Step=STEP_EXIT_DRIVER;
  850.         DriverPtr(&Step,&Ex);
  851.         DriverPtr=NULL;
  852.         Status&=~STATUS_QUIT_DRIVER;
  853.         SendMessage(MSGCODE_DRIVER_QUITED,0);
  854.         Step=Step2;
  855.        }
  856.  
  857.       switch(Status & STATUS_MASK_WAIT)
  858.        {case STATUS_WAIT_IN:
  859.  
  860.           HTWait=INUsed;
  861.           break;
  862.  
  863.         case STATUS_WAIT_OUT:
  864.  
  865.           HTWait=OUTUsed;
  866.           break;
  867.  
  868.         case STATUS_WAIT_DELAY:
  869.  
  870.           HTWait=DelayUsed;
  871.           break;
  872.  
  873.         case STATUS_WAIT_OUT_DELAY:
  874.  
  875.           HTWait=DelayUsed || OUTUsed;
  876.           break;
  877.  
  878.         case STATUS_WAIT_OUT_IN:
  879.  
  880.           HTWait=INUsed || OUTUsed;
  881.           break;
  882.  
  883.         case STATUS_WAIT_ALL:
  884.  
  885.           HTWait=INUsed || OUTUsed || DelayUsed;
  886.           break;
  887.  
  888.         default:
  889.  
  890.           HTWait=FALSE;
  891.        }
  892.  
  893.       if (HTWait)
  894.        {/* Attente de signaux */
  895.         Signals=Wait(MessMask);
  896.         /* S'il s'agit d'un message */
  897.         if (Signals & MessMask)
  898.           /* Récuperation du message */
  899.           while(Mess=GetMsg(ComPort))
  900.            {/* Est-ce la réponse a un de nos message ?*/
  901.             if (Mess->mn_ReplyPort==ComPort)
  902.              {MessagePosted--;
  903.               if (Mess==&(SerialIN->IOSer.io_Message))
  904.                 INUsed=FALSE;
  905.                else
  906.                 if (Mess==&(SerialOUT->IOSer.io_Message))
  907.                  {OUTUsed=FALSE;
  908.                   if (SerialOUT->IOSer.io_Error==-2)
  909.                     SerialOUT->IOSer.io_Error=0;
  910.                  }
  911.                  else
  912.                   if (Mess==&(TimerIO->tr_node.io_Message))
  913.                     DelayUsed=FALSE;
  914.                    else
  915.                     if (((struct LibMessage *)Mess)->Code>=2)
  916.                       FreeMem(Mess,sizeof(struct LibMessage));
  917.                      else
  918.                       MessageUsed[((struct LibMessage *)Mess)->Code]=FALSE;
  919.              }
  920.              else
  921.              {Code=((struct LibMessage *)Mess)->Code;
  922.               DataPtr=((struct LibMessage *)Mess)->Data;
  923.  
  924.               if (DriverPtr || (Code==MSGCODE_NEW_DRIVER) || (Code==MSGCODE_EXIT))
  925.                 switch(Code)
  926.                  {
  927.                   case MSGCODE_ABORT:
  928.                     if (Status & STATUS_REQUEST)
  929.                      {Status&=~STATUS_MASK_WAIT;
  930.                       Step=STEP_REQ_ABORT;
  931.                      }
  932.                     if (Status & STATUS_RECIEVING)
  933.                      {Status&=~STATUS_MASK_WAIT;
  934.                       Step=STEP_ABORT;
  935.                      }
  936.                     if (Status & STATUS_SENDING)
  937.                      {Status&=~STATUS_MASK_WAIT;
  938.                       Step=STEP_SEND_ABORT;
  939.                      }
  940.                     break;
  941.  
  942.                   case MSGCODE_SEND:
  943.                     if (!(Status & STATUS_NOEXIT))
  944.                      {Ex.Node=(struct DumpNode *)DataPtr;
  945.                       Step=STEP_SEND_START;
  946.                       Status&=~STATUS_MASK_WAIT;
  947.                       Status|=STATUS_SENDING;
  948.                      }
  949.                      else
  950.                      ((struct LibMessage *)Mess)->Code|=MSGCODE_IGNORED;
  951.                     break;
  952.  
  953.                   case MSGCODE_EXIT:
  954.                     Status|=STATUS_EXIT;
  955.                     break;
  956.  
  957.                   case MSGCODE_REQUEST:
  958.                     if (!(Status & STATUS_NOEXIT))
  959.                      {Ex.Node=(struct DumpNode *)DataPtr;
  960.                       Step=STEP_REQ_START;
  961.                       Status&=~STATUS_MASK_WAIT;
  962.                       Status|=STATUS_REQUEST;
  963.                      }
  964.                      else
  965.                       ((struct LibMessage *)Mess)->Code|=MSGCODE_IGNORED;
  966.                     break;
  967.  
  968.                   case MSGCODE_QUIT_DRIVER:
  969.                     Status|=STATUS_QUIT_DRIVER;
  970.                     break;
  971.  
  972.                   case MSGCODE_NEW_DRIVER:
  973.                     DriverPtr=DataPtr;
  974.                     Step=STEP_INIT_DRIVER;
  975.                     CallDriver();
  976.                     if (Step==STEP_EXIT_DRIVER)
  977.                      {DriverPtr=NULL;
  978.                       ((struct LibMessage *)Mess)->Code|=MSGCODE_IGNORED;
  979.                      }
  980.                      else
  981.                      {Step=STEP_WAIT;
  982.                       Status&=~STATUS_MASK_WAIT;
  983.                      }
  984.                     break;
  985.                  }
  986.                else
  987.                  ((struct LibMessage *)Mess)->Code|=MSGCODE_IGNORED;
  988.               ReplyMsg((struct Message *)Mess);
  989.              }
  990.            }
  991.        }
  992.        else
  993.        {Status&=~STATUS_MASK_WAIT;
  994.         Advance();
  995.        }
  996.      }
  997.    }
  998.   CloseComTask();
  999. }
  1000.