home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 500-599 / ff589.lza / Term / TermSrc.lha / Serial.c < prev    next >
C/C++ Source or Header  |  1991-12-01  |  10KB  |  550 lines

  1. /* $Revision Header * Header built automatically - do not edit! *************
  2.  *
  3.  *    (C) Copyright 1991 by Olaf 'Olsen' Barthel & MXM
  4.  *
  5.  *    Name .....: Serial.c
  6.  *    Created ..: Monday 21-Jan-91 20:12
  7.  *    Revision .: 0
  8.  *
  9.  *    Date            Author          Comment
  10.  *    =========       ========        ====================
  11.  *    21-Jan-91       Olsen           Created this file!
  12.  *
  13.  * $Revision Header ********************************************************/
  14.  
  15. #include "TermGlobal.h"
  16.  
  17.     /* XOn():
  18.      *
  19.      *    Perform XON (stop data flow).
  20.      */
  21.  
  22. VOID
  23. XOn()
  24. {
  25.     if(Config . Handshaking == HANDSHAKING_XONXOFF)
  26.         Status = STATUS_HOLDING;
  27. }
  28.  
  29.     /* SerialCommand(UBYTE *String):
  30.      *
  31.      *    Send a command string to the serial line and
  32.      *    interprete the control sequences.
  33.      */
  34.  
  35. VOID
  36. SerialCommand(UBYTE *String)
  37. {
  38.     LONG    Count = 0,i;
  39.  
  40.     BYTE    GotControl    = FALSE,
  41.         GotEscape    = FALSE,
  42.  
  43.         OldStatus,
  44.         BlockSet;
  45.  
  46.         /* Scan the string. */
  47.  
  48.     for(i = 0 ; i < strlen(String) ; i++)
  49.     {
  50.             /* We are looking for plain characters
  51.              * and the control ('\') and escape
  52.              * ('^') characters.
  53.              */
  54.  
  55.         if(!GotControl && !GotEscape)
  56.         {
  57.                 /* Got a control character,
  58.                  * the next byte will probably be
  59.                  * a command sequence.
  60.                  */
  61.  
  62.             if(String[i] == '\\')
  63.             {
  64.                 GotControl = TRUE;
  65.                 continue;
  66.             }
  67.  
  68.                 /* Got an escape character,
  69.                  * the next byte will be some
  70.                  * kind of control character
  71.                  * (such as XON, XOF, bell, etc.).
  72.                  */
  73.  
  74.             if(String[i] == '^')
  75.             {
  76.                 GotEscape = TRUE;
  77.                 continue;
  78.             }
  79.  
  80.                 /* This tells us to wait another
  81.                  * second before continuing with
  82.                  * the scanning.
  83.                  */
  84.  
  85.             if(String[i] == '~')
  86.             {
  87.                 if(Count)
  88.                 {
  89.                     SerWrite(SharedBuffer,Count);
  90.  
  91.                     Count = 0;
  92.                 }
  93.  
  94.                 WaitTime(0,MILLION / 2);
  95.                 HandleSerial();
  96.  
  97.                 continue;
  98.             }
  99.  
  100.                 /* Stuff the character into the
  101.                  * buffer.
  102.                  */
  103.  
  104.             SharedBuffer[Count++] = String[i];
  105.         }
  106.         else
  107.         {
  108.                 /* Convert the character to a control
  109.                  * style character (^C, etc.).
  110.                  */
  111.  
  112.             if(GotEscape)
  113.             {
  114.                 if(ToUpper(String[i]) >= 'A' && ToUpper(String[i]) <= 91)
  115.                     SharedBuffer[Count++] = ToUpper(String[i]) - '@';
  116.                 else
  117.                     SharedBuffer[Count++] = String[i];
  118.  
  119.                 GotEscape = FALSE;
  120.             }
  121.  
  122.                 /* The next character represents a command. */
  123.  
  124.             if(GotControl)
  125.             {
  126.                 switch(ToUpper(String[i]))
  127.                 {
  128.                         /* Execute an AmigaDOS command. */
  129.  
  130.                     case 'D':    if(!WeAreBlocking)
  131.                             {
  132.                                 BlockSet = TRUE;
  133.  
  134.                                 BlockWindows();
  135.                             }
  136.                             else
  137.                                 BlockSet = FALSE;
  138.  
  139.                             SendAmigaDOSCommand(&String[i + 1]);
  140.  
  141.                             if(BlockSet)
  142.                                 ReleaseWindows();
  143.  
  144.                             return;
  145.  
  146.                         /* Execute an ARexx command. */
  147.  
  148.                     case 'A':    if(!WeAreBlocking)
  149.                             {
  150.                                 BlockSet = TRUE;
  151.  
  152.                                 BlockWindows();
  153.                             }
  154.                             else
  155.                                 BlockSet = FALSE;
  156.  
  157.                             SendARexxCommand(&String[i + 1]);
  158.  
  159.                             if(BlockSet)
  160.                                 ReleaseWindows();
  161.  
  162.                             return;
  163.  
  164.                         /* Add the control character ('\'). */
  165.  
  166.                     case '\\':    SharedBuffer[Count++] = '\\';
  167.                             break;
  168.  
  169.                         /* This is a backspace. */
  170.  
  171.                     case 'B':    SharedBuffer[Count++] = '\b';
  172.                             break;
  173.  
  174.                         /* This is a form feed. */
  175.  
  176.                     case 'F':    SharedBuffer[Count++] = '\f';
  177.                             break;
  178.  
  179.                         /* This is a line feed. */
  180.  
  181.                     case 'N':    SharedBuffer[Count++] = '\n';
  182.                             break;
  183.  
  184.                         /* Send the current password. */
  185.  
  186.                     case 'P':    if(Password[0])
  187.                             {
  188.                                 if(Count)
  189.                                 {
  190.                                     SerWrite(SharedBuffer,Count);
  191.  
  192.                                     Count = 0;
  193.                                 }
  194.  
  195.                                 SerWrite(Password,strlen(Password));
  196.                             }
  197.  
  198.                             break;
  199.  
  200.                         /* This is a carriage return. */
  201.  
  202.                     case 'R':    SharedBuffer[Count++] = '\r';
  203.                             break;
  204.  
  205.                         /* This is a tab. */
  206.  
  207.                     case 'T':    SharedBuffer[Count++] = '\t';
  208.                             break;
  209.  
  210.                         /* Send a break across the serial line. */
  211.  
  212.                     case 'X':    if(Count)
  213.                             {
  214.                                 SerWrite(SharedBuffer,Count);
  215.  
  216.                                 Count = 0;
  217.                             }
  218.  
  219.                             if(WriteRequest)
  220.                             {
  221.                                 OldStatus = Status;
  222.  
  223.                                 Status = STATUS_BREAKING;
  224.  
  225.                                 WriteRequest -> IOSer . io_Command = SDCMD_BREAK;
  226.                                 DoIO(WriteRequest);
  227.  
  228.                                 Status = OldStatus;
  229.                             }
  230.  
  231.                             break;
  232.  
  233.                         /* Feed the contents of the
  234.                          * clipboard into the input
  235.                          * stream.
  236.                          */
  237.  
  238.                     case 'I':    if(Count)
  239.                                 SerWrite(SharedBuffer,Count);
  240.  
  241.                             Count = LoadClip(SharedBuffer,256);
  242.  
  243.                             break;
  244.  
  245.                         /* Send a string to the clipboard. */
  246.  
  247.                     case 'G':    if(String[i + 1])
  248.                                 SaveClip(&String[i + 1],strlen(&String[i + 1]));
  249.  
  250.                             return;
  251.  
  252.                         /* Produce the escape character. */
  253.  
  254.                     case 'E':    SharedBuffer[Count++] = ESC;
  255.                             break;
  256.  
  257.                         /* Stuff the character into the buffer. */
  258.  
  259.                     default:    SharedBuffer[Count++] = String[i];
  260.                             break;
  261.                 }
  262.  
  263.                 GotControl = FALSE;
  264.             }
  265.         }
  266.  
  267.             /* If the buffer is full, release it. */
  268.  
  269.         if(Count == 256)
  270.         {
  271.             SerWrite(SharedBuffer,Count);
  272.  
  273.             Count = 0;
  274.         }
  275.     }
  276.  
  277.     if(Count)
  278.         SerWrite(SharedBuffer,Count);
  279. }
  280.  
  281.     /* SerWrite(APTR Buffer,LONG Size):
  282.      *
  283.      *    Send a number of bytes across the serial line.
  284.      */
  285.  
  286. VOID
  287. SerWrite(APTR Buffer,LONG Size)
  288. {
  289.     if(WriteRequest && Size)
  290.     {
  291.         if(XProtocolBase)
  292.         {
  293.                 /* xpr wants to see the data before it is
  294.                  * transferred.
  295.                  */
  296.  
  297.             if(TransferBits & XPRS_USERMON)
  298.                 if(!(Size = XProtocolUserMon(XprIO,Buffer,Size,Size)))
  299.                     return;
  300.         }
  301.  
  302.             /* If full duplex is enabled, send the entire
  303.              * buffer.
  304.              */
  305.  
  306.         if(Config . Duplex == DUPLEX_FULL)
  307.         {
  308.             WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  309.             WriteRequest -> IOSer . io_Data        = Buffer;
  310.             WriteRequest -> IOSer . io_Length    = Size;
  311.  
  312.             DoIO(WriteRequest);
  313.         }
  314.         else
  315.         {
  316.             UBYTE *ByteBuffer = Buffer;
  317.  
  318.                 /* Half duplex is enabled, send only
  319.                  * a single character at a time.
  320.                  */
  321.  
  322.             WriteRequest -> IOSer . io_Command    = CMD_WRITE;
  323.             WriteRequest -> IOSer . io_Length    = 1;
  324.  
  325.             while(Size--)
  326.             {
  327.                 WriteRequest -> IOSer . io_Data = ByteBuffer;
  328.  
  329.                 DoIO(WriteRequest);
  330.  
  331.                 ConProcess(ByteBuffer,1);
  332.  
  333.                 ByteBuffer++;
  334.             }
  335.         }
  336.     }
  337. }
  338.  
  339.     /* SetFlags(struct IOExtSer *SomeRequest):
  340.      *
  341.      *    Set the contents of a serial device request according
  342.      *    to the current configuration settings.
  343.      */
  344.  
  345. VOID
  346. SetFlags(struct IOExtSer *SomeRequest)
  347. {
  348.     SomeRequest -> io_Baud        = Config . BaudRate;
  349.     SomeRequest -> io_BrkTime    = Config . BreakLength;
  350.     SomeRequest -> io_ReadLen    = Config . BitsPerChar;
  351.     SomeRequest -> io_WriteLen    = Config . BitsPerChar;
  352.     SomeRequest -> io_StopBits    = Config . StopBits;
  353.  
  354.     SomeRequest -> io_ExtFlags    &= ~(SEXTF_MSPON|SEXTF_MARK);
  355.     SomeRequest -> io_SerFlags    &= ~(SERF_PARTY_ON|SERF_PARTY_ODD|SERF_7WIRE|SERF_RAD_BOOGIE);
  356.  
  357.     switch(Config . Parity)
  358.     {
  359.         case PARITY_EVEN:    SomeRequest -> io_SerFlags |= SERF_PARTY_ON;
  360.                     break;
  361.  
  362.         case PARITY_ODD:    SomeRequest -> io_SerFlags |= SERF_PARTY_ON|SERF_PARTY_ODD;
  363.                     break;
  364.  
  365.         case PARITY_MARK:    SomeRequest -> io_SerFlags |= SERF_PARTY_ON;
  366.                     SomeRequest -> io_ExtFlags |= SEXTF_MSPON|SEXTF_MARK;
  367.                     break;
  368.  
  369.         case PARITY_SPACE:    SomeRequest -> io_SerFlags |= SERF_PARTY_ON;
  370.                     SomeRequest -> io_ExtFlags |= SEXTF_MSPON;
  371.                     break;
  372.  
  373.         default:        break;
  374.     }
  375.  
  376.     if(Config . Handshaking == HANDSHAKING_RTSCTS)
  377.         SomeRequest -> io_SerFlags |= SERF_7WIRE;
  378.  
  379.     if(Config . HighSpeed)
  380.         SomeRequest -> io_SerFlags |= SERF_RAD_BOOGIE;
  381.  
  382.     SomeRequest -> io_SerFlags |= SERF_XDISABLED;
  383. }
  384.  
  385.     /* SetParameters():
  386.      *
  387.      *    Set the parameters for both serial requests and the
  388.      *    serial line.
  389.      */
  390.  
  391. VOID
  392. SetParameters()
  393. {
  394.     if(WriteRequest)
  395.     {
  396.         WriteRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
  397.  
  398.         SetFlags(WriteRequest);
  399.         SetFlags(ReadRequest);
  400.  
  401.         DoIO(WriteRequest);
  402.     }
  403. }
  404.  
  405.     /* FlushSerial():
  406.      *
  407.      *    Marks the current serial read buffer as invalid.
  408.      */
  409.  
  410. VOID
  411. FlushSerial()
  412. {
  413.     if(WriteRequest)
  414.     {
  415.         WriteRequest -> IOSer . io_Command = CMD_FLUSH;
  416.         DoIO(WriteRequest);
  417.     }
  418. }
  419.  
  420.     /* ClearSerial():
  421.      *
  422.      *    Terminate all read/write activity on the serial
  423.      *    line.
  424.      */
  425.  
  426. VOID
  427. ClearSerial()
  428. {
  429.     if(ReadPort)
  430.     {
  431.         if(!CheckIO(ReadRequest))
  432.             AbortIO(ReadRequest);
  433.  
  434.         WaitIO(ReadRequest);
  435.  
  436.         WriteRequest -> IOSer . io_Command = CMD_CLEAR;
  437.  
  438.         DoIO(WriteRequest);
  439.     }
  440. }
  441.  
  442.     /* DeleteSerial():
  443.      *
  444.      *    Close the serial device and release all associated
  445.      *    resources.
  446.      */
  447.  
  448. VOID
  449. DeleteSerial()
  450. {
  451.     BYTE Closed = FALSE;
  452.  
  453.     if(ReadBuffer)
  454.     {
  455.         FreeVec(ReadBuffer);
  456.  
  457.         ReadBuffer = NULL;
  458.     }
  459.  
  460.     if(ReadRequest)
  461.     {
  462.         if(ReadRequest -> IOSer . io_Device)
  463.         {
  464.             ReadRequest -> IOSer . io_Command = CMD_RESET;
  465.  
  466.             DoIO(ReadRequest);
  467.  
  468.             CloseDevice(ReadRequest);
  469.  
  470.             Closed = TRUE;
  471.         }
  472.  
  473.         if(ReadRequest -> IOSer . io_Message . mn_ReplyPort)
  474.             DeleteMsgPort(ReadRequest -> IOSer . io_Message . mn_ReplyPort);
  475.  
  476.         DeleteIORequest(ReadRequest);
  477.  
  478.         ReadRequest = NULL;
  479.     }
  480.  
  481.     if(WriteRequest)
  482.     {
  483.         if(WriteRequest -> IOSer . io_Device && !Closed)
  484.         {
  485.             WriteRequest -> IOSer . io_Command = CMD_RESET;
  486.             DoIO(WriteRequest);
  487.  
  488.             CloseDevice(WriteRequest);
  489.         }
  490.  
  491.         if(WriteRequest -> IOSer . io_Message . mn_ReplyPort)
  492.             DeleteMsgPort(WriteRequest -> IOSer . io_Message . mn_ReplyPort);
  493.  
  494.         DeleteIORequest(WriteRequest);
  495.  
  496.         WriteRequest = NULL;
  497.     }
  498.  
  499.     ReadPort = NULL;
  500. }
  501.  
  502.     /* CreateSerial():
  503.      *
  504.      *    Create handles for the serial device and open it.
  505.      */
  506.  
  507. BYTE
  508. CreateSerial()
  509. {
  510.     struct MsgPort    *WritePort;
  511.  
  512.     if(ReadBuffer = AllocVec(SERBUFF_SIZE,MEMF_PUBLIC))
  513.     {
  514.         if(ReadPort = (struct MsgPort *)CreateMsgPort())
  515.         {
  516.             if(ReadRequest = (struct IOExtSer *)CreateIORequest(ReadPort,sizeof(struct IOExtSer)))
  517.             {
  518.                 SetFlags(ReadRequest);
  519.  
  520.                 ReadRequest -> io_RBufLen = SERBUFF_SIZE;
  521.  
  522.                 if(!OpenDevice(Config . SerialDevice,Config . UnitNumber,ReadRequest,0))
  523.                 {
  524.                     if(WritePort = (struct MsgPort *)CreateMsgPort())
  525.                     {
  526.                         if(WriteRequest = (struct IOExtSer *)CreateIORequest(WritePort,sizeof(struct IOExtSer)))
  527.                         {
  528.                             CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
  529.  
  530.                             WriteRequest -> IOSer . io_Message . mn_ReplyPort = WritePort;
  531.  
  532.                             SetParameters();
  533.  
  534.                             ReadRequest -> IOSer . io_Command    = CMD_READ;
  535.                             ReadRequest -> IOSer . io_Data        = ReadBuffer;
  536.                             ReadRequest -> IOSer . io_Length    = 1;
  537.  
  538.                             SendIO(ReadRequest);
  539.  
  540.                             return(TRUE);
  541.                         }
  542.                     }
  543.                 }
  544.             }
  545.         }
  546.     }
  547.  
  548.     return(FALSE);
  549. }
  550.