home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / bbs / termv4.6 / extras / source / term-source.lha / SerialIO.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-18  |  11.5 KB  |  739 lines

  1. /*
  2. **    SerialIO.c
  3. **
  4. **    Serial read/write routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16. STATIC BOOLEAN __aligned    ReadQueued    = FALSE,
  17.                             WriteQueued    = FALSE;
  18.  
  19.     /* ResetSerialRead():
  20.      *
  21.      *    Reset the read status.
  22.      */
  23.  
  24. VOID
  25. ResetSerialRead()
  26. {
  27.     ReadQueued = FALSE;
  28. }
  29.  
  30.     /* CheckSerialRead():
  31.      *
  32.      *    Check if a read request is finished.
  33.      */
  34.  
  35. BOOL
  36. CheckSerialRead()
  37. {
  38.     if(ReadRequest && ReadQueued)
  39.     {
  40.         if(CheckIO(ReadRequest))
  41.             return(TRUE);
  42.     }
  43.  
  44.     return(FALSE);
  45. }
  46.  
  47.     /* WaitSerialRead():
  48.      *
  49.      *    Wait for the read request to terminate.
  50.      */
  51.  
  52. BYTE
  53. WaitSerialRead()
  54. {
  55.     if(ReadRequest && ReadQueued)
  56.     {
  57.         ReadQueued = FALSE;
  58.  
  59.         return(WaitIO(ReadRequest));
  60.     }
  61.     else
  62.         return(0);
  63. }
  64.  
  65.     /* FlushSerialRead():
  66.      *
  67.      *    Forget about the current contents of the serial
  68.      *    read buffer.
  69.      */
  70.  
  71. BYTE
  72. FlushSerialRead()
  73. {
  74.     if(ReadRequest)
  75.     {
  76.         BOOL WasRunning;
  77.  
  78.         if(WasRunning = ReadQueued)
  79.             StopSerialRead();
  80.  
  81.         ReadRequest->IOSer.io_Command = CMD_CLEAR;
  82.  
  83.         DoIO(ReadRequest);
  84.  
  85.         if(WasRunning)
  86.             StartSerialRead(ReadBuffer,1);
  87.     }
  88.  
  89.     return(0);
  90. }
  91.  
  92.     /* StopSerialRead():
  93.      *
  94.      *    Force a read request to terminate.
  95.      */
  96.  
  97. VOID
  98. StopSerialRead()
  99. {
  100.     if(ReadRequest && ReadQueued)
  101.     {
  102.         if(!CheckIO(ReadRequest))
  103.             AbortIO(ReadRequest);
  104.  
  105.         WaitIO(ReadRequest);
  106.  
  107.         ReadQueued = FALSE;
  108.     }
  109. }
  110.  
  111.     /* StartSerialRead(register ULONG Length,register APTR Data):
  112.      *
  113.      *    Start a serial read request asynchronously.
  114.      */
  115.  
  116. VOID
  117. StartSerialRead(register APTR Data,register ULONG Length)
  118. {
  119.     if(ReadRequest)
  120.     {
  121.         if(ReadQueued)
  122.             StopSerialRead();
  123.  
  124.         ReadRequest->IOSer.io_Command    = CMD_READ;
  125.         ReadRequest->IOSer.io_Length    = Length;
  126.         ReadRequest->IOSer.io_Data        = Data;
  127.  
  128.         ClrSignal(1L << ReadPort->mp_SigBit);
  129.  
  130.         SendIO(ReadRequest);
  131.  
  132.         ReadQueued = TRUE;
  133.     }
  134. }
  135.  
  136.     /* DoSerialRead(register ULONG Length,register APTR Data):
  137.      *
  138.      *    Perform a read request synchronously.
  139.      */
  140.  
  141. BYTE
  142. DoSerialRead(register APTR Data,register ULONG Length)
  143. {
  144.     if(ReadRequest)
  145.     {
  146.         if(ReadQueued)
  147.             StopSerialRead();
  148.  
  149.         ReadRequest->IOSer.io_Command    = CMD_READ;
  150.         ReadRequest->IOSer.io_Length    = Length;
  151.         ReadRequest->IOSer.io_Data        = Data;
  152.  
  153.         return(DoIO(ReadRequest));
  154.     }
  155.     else
  156.         return(IOERR_SELFTEST);
  157. }
  158.  
  159.     /* ResetSerialWrite():
  160.      *
  161.      *    Reset the write status.
  162.      */
  163.  
  164. VOID
  165. ResetSerialWrite()
  166. {
  167.     WriteQueued = FALSE;
  168. }
  169.  
  170.     /* CheckSerialWrite():
  171.      *
  172.      *    Check if a write request is finished.
  173.      */
  174.  
  175. BOOL
  176. CheckSerialWrite()
  177. {
  178.     if(WriteRequest && WriteQueued)
  179.     {
  180.         if(!CheckIO(WriteRequest))
  181.             return(TRUE);
  182.     }
  183.  
  184.     return(FALSE);
  185. }
  186.  
  187.     /* WaitSerialWrite():
  188.      *
  189.      *    Wait for the write request to terminate.
  190.      */
  191.  
  192. BYTE
  193. WaitSerialWrite()
  194. {
  195.     if(WriteRequest && WriteQueued)
  196.     {
  197.         WriteQueued = FALSE;
  198.  
  199.         return(WaitIO(WriteRequest));
  200.     }
  201.     else
  202.         return(0);
  203. }
  204.  
  205.     /* StopSerialWrite():
  206.      *
  207.      *    Force a write request to terminate.
  208.      */
  209.  
  210. VOID
  211. StopSerialWrite()
  212. {
  213.     if(WriteRequest && WriteQueued)
  214.     {
  215.         if(!CheckIO(WriteRequest))
  216.             AbortIO(WriteRequest);
  217.  
  218.         WaitIO(WriteRequest);
  219.  
  220.         WriteQueued = FALSE;
  221.     }
  222. }
  223.  
  224.     /* StartSerialWrite(register ULONG Length,register APTR Data):
  225.      *
  226.      *    Start a serial write request asynchronously.
  227.      */
  228.  
  229. VOID
  230. StartSerialWrite(register APTR Data,register ULONG Length)
  231. {
  232.     if(WriteRequest)
  233.     {
  234.         if(WriteQueued)
  235.             StopSerialWrite();
  236.  
  237.         WriteRequest->IOSer.io_Command    = CMD_WRITE;
  238.         WriteRequest->IOSer.io_Length    = Length;
  239.         WriteRequest->IOSer.io_Data        = Data;
  240.  
  241.         ClrSignal(1L << WriteRequest->IOSer.io_Message.mn_ReplyPort->mp_SigBit);
  242.  
  243.         SendIO(WriteRequest);
  244.  
  245.         WriteQueued = TRUE;
  246.     }
  247. }
  248.  
  249.     /* DoSerialWrite(register ULONG Length,register APTR Data):
  250.      *
  251.      *    Perform a write request synchronously.
  252.      */
  253.  
  254. BYTE
  255. DoSerialWrite(register APTR Data,register ULONG Length)
  256. {
  257.     if(WriteRequest)
  258.     {
  259.         if(WriteQueued)
  260.             StopSerialWrite();
  261.  
  262.         WriteRequest->IOSer.io_Command    = CMD_WRITE;
  263.         WriteRequest->IOSer.io_Length    = Length;
  264.         WriteRequest->IOSer.io_Data        = Data;
  265.  
  266.         return(DoIO(WriteRequest));
  267.     }
  268.     else
  269.         return(IOERR_SELFTEST);
  270. }
  271.  
  272.     /* DoSerialCmd(register UWORD Command):
  273.      *
  274.      *    Perform single command.
  275.      */
  276.  
  277. BYTE
  278. DoSerialCmd(register LONG Command)
  279. {
  280.     if(WriteRequest)
  281.     {
  282.         if(WriteQueued)
  283.             StopSerialWrite();
  284.  
  285.         WriteRequest->IOSer.io_Command = Command;
  286.  
  287.         return(DoIO(WriteRequest));
  288.     }
  289.     else
  290.         return(IOERR_SELFTEST);
  291. }
  292.  
  293.     /* GetSerialWaiting():
  294.      *
  295.      *    Query the number of bytes still waiting to be read
  296.      *    from the serial port.
  297.      */
  298.  
  299. ULONG
  300. GetSerialWaiting()
  301. {
  302.     if(WriteRequest)
  303.     {
  304.         if(WriteQueued)
  305.             StopSerialWrite();
  306.  
  307.         WriteRequest->IOSer.io_Command = SDCMD_QUERY;
  308.  
  309.         DoIO(WriteRequest);
  310.  
  311.         return(WriteRequest->IOSer.io_Actual);
  312.     }
  313.     else
  314.         return(0);
  315. }
  316.  
  317.     /* GetSerialStatus():
  318.      *
  319.      *    Query the current serial port status.
  320.      */
  321.  
  322. LONG
  323. GetSerialStatus()
  324. {
  325.     if(WriteRequest)
  326.     {
  327.         if(WriteQueued)
  328.             StopSerialWrite();
  329.  
  330.         WriteRequest->IOSer.io_Command = SDCMD_QUERY;
  331.  
  332.         DoIO(WriteRequest);
  333.  
  334.         return(WriteRequest->io_Status);
  335.     }
  336.     else
  337.         return(CIAF_COMCD | CIAF_COMDSR);
  338. }
  339.  
  340.     /* GetSerialInfo(register ULONG *Waiting,register UWORD *Status):
  341.      *
  342.      *    Query both the number of bytes waiting to be read and
  343.      *    the current serial status.
  344.      */
  345.  
  346. VOID
  347. GetSerialInfo(register ULONG *Waiting,register UWORD *Status)
  348. {
  349.     if(WriteRequest)
  350.     {
  351.         if(WriteQueued)
  352.             StopSerialWrite();
  353.  
  354.         WriteRequest->IOSer.io_Command = SDCMD_QUERY;
  355.  
  356.         DoIO(WriteRequest);
  357.  
  358.         *Waiting    = WriteRequest->IOSer.io_Actual;
  359.         *Status        = WriteRequest->io_Status;
  360.     }
  361.     else
  362.     {
  363.         *Waiting    = 0;
  364.         *Status        = CIAF_COMCD | CIAF_COMDSR;
  365.     }
  366. }
  367.  
  368.     /* SetSerialAttributes():
  369.      *
  370.      *    Set the serial driver attributes.
  371.      */
  372.  
  373. STATIC VOID
  374. SetSerialAttributes(struct IOExtSer *Request,struct TagItem *Tags)
  375. {
  376.     struct TagItem *Tag;
  377.  
  378.     while(Tag = NextTagItem(&Tags))
  379.     {
  380.         switch(Tag->ti_Tag)
  381.         {
  382.             case SERA_Baud:
  383.  
  384.                 Request->io_Baud = Tag->ti_Data;
  385.                 break;
  386.  
  387.             case SERA_BreakTime:
  388.  
  389.                 Request->io_BrkTime = Tag->ti_Data;
  390.                 break;
  391.  
  392.             case SERA_BitsPerChar:
  393.  
  394.                 Request->io_ReadLen    = Tag->ti_Data;
  395.                 Request->io_WriteLen    = Tag->ti_Data;
  396.                 break;
  397.  
  398.             case SERA_StopBits:
  399.  
  400.                 Request->io_StopBits = Tag->ti_Data;
  401.                 break;
  402.  
  403.             case SERA_BufferSize:
  404.  
  405.                 Request->io_RBufLen = Tag->ti_Data;
  406.                 break;
  407.  
  408.             case SERA_Parity:
  409.  
  410.                 Request->io_ExtFlags &= ~(SEXTF_MSPON | SEXTF_MARK);
  411.                 Request->io_SerFlags &= ~(SERF_PARTY_ON | SERF_PARTY_ODD);
  412.  
  413.                 switch(Tag->ti_Data)
  414.                 {
  415.                     case PARITY_EVEN:
  416.  
  417.                         Request->io_SerFlags |= SERF_PARTY_ON;
  418.                         break;
  419.  
  420.                     case PARITY_ODD:
  421.  
  422.                         Request->io_SerFlags |= SERF_PARTY_ON | SERF_PARTY_ODD;
  423.                         break;
  424.  
  425.                     case PARITY_MARK:
  426.  
  427.                         Request->io_SerFlags |= SERF_PARTY_ON;
  428.                         Request->io_ExtFlags |= SEXTF_MSPON | SEXTF_MARK;
  429.                         break;
  430.  
  431.                     case PARITY_SPACE:
  432.  
  433.                         Request->io_SerFlags |= SERF_PARTY_ON;
  434.                         Request->io_ExtFlags |= SEXTF_MSPON;
  435.                         break;
  436.                 }
  437.  
  438.                 break;
  439.  
  440.             case SERA_Handshaking:
  441.  
  442.                 if(Tag->ti_Data == HANDSHAKING_NONE)
  443.                     Request->io_SerFlags &= ~SERF_7WIRE;
  444.                 else
  445.                     Request->io_SerFlags |=  SERF_7WIRE;
  446.  
  447.                 break;
  448.  
  449.             case SERA_HighSpeed:
  450.  
  451.                 if(Tag->ti_Data)
  452.                     Request->io_SerFlags |=  SERF_RAD_BOOGIE;
  453.                 else
  454.                     Request->io_SerFlags &= ~SERF_RAD_BOOGIE;
  455.  
  456.                 break;
  457.  
  458.             case SERA_Shared:
  459.  
  460.                 if(Tag->ti_Data)
  461.                     Request->io_SerFlags |=  SERF_SHARED;
  462.                 else
  463.                     Request->io_SerFlags &= ~SERF_SHARED;
  464.  
  465.                 break;
  466.         }
  467.     }
  468.  
  469.     Request->io_SerFlags |= SERF_XDISABLED;
  470. }
  471.  
  472.     /* GetSerialAttributes():
  473.      *
  474.      *    Get the serial driver attributes.
  475.      */
  476.  
  477. STATIC ULONG
  478. GetSerialAttributes(struct IOExtSer *Request,struct TagItem *Tags)
  479. {
  480.     struct TagItem    *Tag;
  481.     ULONG            *Data;
  482.     ULONG             Result;
  483.  
  484.     Result = NULL;
  485.  
  486.     while(Tag = NextTagItem(&Tags))
  487.     {
  488.         if(!(Data = (ULONG *)Tag->ti_Data))
  489.             Data = &Result;
  490.  
  491.         switch(Tag->ti_Tag)
  492.         {
  493.             case SERA_Baud:
  494.  
  495.                 *Data = Request->io_Baud;
  496.                 break;
  497.  
  498.             case SERA_BreakTime:
  499.  
  500.                 *Data = Request->io_BrkTime;
  501.                 break;
  502.  
  503.             case SERA_BitsPerChar:
  504.  
  505.                 *Data = Request->io_ReadLen;
  506.                 break;
  507.  
  508.             case SERA_StopBits:
  509.  
  510.                 *Data = Request->io_StopBits;
  511.                 break;
  512.  
  513.             case SERA_BufferSize:
  514.  
  515.                 *Data = Request->io_RBufLen;
  516.                 break;
  517.  
  518.             case SERA_Parity:
  519.  
  520.                 Request->io_ExtFlags &= ~(SEXTF_MSPON | SEXTF_MARK);
  521.                 Request->io_SerFlags &= ~(SERF_PARTY_ON | SERF_PARTY_ODD);
  522.  
  523.                 switch(Tag->ti_Data)
  524.                 {
  525.                     case PARITY_EVEN:
  526.  
  527.                         Request->io_SerFlags |= SERF_PARTY_ON;
  528.                         break;
  529.  
  530.                     case PARITY_ODD:
  531.  
  532.                         Request->io_SerFlags |= SERF_PARTY_ON | SERF_PARTY_ODD;
  533.                         break;
  534.  
  535.                     case PARITY_MARK:
  536.  
  537.                         Request->io_SerFlags |= SERF_PARTY_ON;
  538.                         Request->io_ExtFlags |= SEXTF_MSPON | SEXTF_MARK;
  539.                         break;
  540.  
  541.                     case PARITY_SPACE:
  542.  
  543.                         Request->io_SerFlags |= SERF_PARTY_ON;
  544.                         Request->io_ExtFlags |= SEXTF_MSPON;
  545.                         break;
  546.                 }
  547.  
  548.                 switch(Request->io_ExtFlags & (SEXTF_MSPON | SEXTF_MARK))
  549.                 {
  550.                     case SEXTF_MSPON | SEXTF_MARK:
  551.  
  552.                         *Data = PARITY_MARK;
  553.                         break;
  554.  
  555.                     case SEXTF_MSPON:
  556.  
  557.                         *Data = PARITY_SPACE;
  558.                         break;
  559.  
  560.                     default:
  561.  
  562.                         switch(Request->io_SerFlags & (SERF_PARTY_ON | SERF_PARTY_ODD))
  563.                         {
  564.                             case SERF_PARTY_ON | SERF_PARTY_ODD:
  565.  
  566.                                 *Data = PARITY_ODD;
  567.                                 break;
  568.  
  569.                             case SERF_PARTY_ON:
  570.  
  571.                                 *Data = PARITY_EVEN;
  572.                                 break;
  573.  
  574.                             default:
  575.  
  576.                                 *Data = PARITY_NONE;
  577.                                 break;
  578.                         }
  579.  
  580.                         break;
  581.                 }
  582.  
  583.                 break;
  584.  
  585.             case SERA_Handshaking:
  586.  
  587.                 if(Request->io_SerFlags & SERF_7WIRE)
  588.                     *Data = TRUE;
  589.                 else
  590.                     *Data = FALSE;
  591.  
  592.                 break;
  593.  
  594.             case SERA_HighSpeed:
  595.  
  596.                 if(Request->io_SerFlags & SERF_RAD_BOOGIE)
  597.                     *Data = TRUE;
  598.                 else
  599.                     *Data = FALSE;
  600.  
  601.                 break;
  602.  
  603.             case SERA_Shared:
  604.  
  605.                 if(Request->io_SerFlags & SERF_SHARED)
  606.                     *Data = TRUE;
  607.                 else
  608.                     *Data = FALSE;
  609.  
  610.                 break;
  611.         }
  612.     }
  613.  
  614.     return(Result);
  615. }
  616.  
  617.     /* SetBothSerialAttributes():
  618.      *
  619.      *    Set the serial read driver parameters.
  620.      */
  621.  
  622. BYTE __stdargs
  623. SetBothSerialAttributes(Tag FirstTag,...)
  624. {
  625.     if(ReadRequest && WriteRequest)
  626.     {
  627.         BYTE Result;
  628.  
  629.         if(ReadQueued)
  630.             StopSerialRead();
  631.  
  632.         if(WriteQueued)
  633.             StopSerialWrite();
  634.  
  635.         SetSerialAttributes(ReadRequest,(struct TagItem *)&FirstTag);
  636.  
  637.         if(ReadRequest->IOSer.io_Device)
  638.         {
  639.             ReadRequest->IOSer.io_Command = SDCMD_SETPARAMS;
  640.  
  641.             Result = DoIO(ReadRequest);
  642.         }
  643.         else
  644.             Result = 0;
  645.  
  646.         if(!Result)
  647.         {
  648.             struct MsgPort *WritePort = WriteRequest->IOSer.io_Message.mn_ReplyPort;
  649.  
  650.             CopyMem(ReadRequest,WriteRequest,sizeof(struct IOExtSer));
  651.  
  652.             WriteRequest->IOSer.io_Message.mn_ReplyPort = WritePort;
  653.         }
  654.  
  655.         return(Result);
  656.     }
  657.     else
  658.         return(IOERR_SELFTEST);
  659. }
  660.  
  661.     /* SetSerialReadAttributes():
  662.      *
  663.      *    Set the serial read driver parameters.
  664.      */
  665.  
  666. BYTE __stdargs
  667. SetSerialReadAttributes(Tag FirstTag,...)
  668. {
  669.     if(ReadRequest)
  670.     {
  671.         if(ReadQueued)
  672.             StopSerialRead();
  673.  
  674.         SetSerialAttributes(ReadRequest,(struct TagItem *)&FirstTag);
  675.  
  676.         if(ReadRequest->IOSer.io_Device)
  677.         {
  678.             ReadRequest->IOSer.io_Command = SDCMD_SETPARAMS;
  679.  
  680.             return(DoIO(ReadRequest));
  681.         }
  682.         else
  683.             return(0);
  684.     }
  685.     else
  686.         return(IOERR_SELFTEST);
  687. }
  688.  
  689.     /* SetSerialWriteAttributes():
  690.      *
  691.      *    Set the serial write driver parameters.
  692.      */
  693.  
  694. BYTE __stdargs
  695. SetSerialWriteAttributes(Tag FirstTag,...)
  696. {
  697.     if(WriteRequest)
  698.     {
  699.         if(WriteQueued)
  700.             StopSerialWrite();
  701.  
  702.         SetSerialAttributes(WriteRequest,(struct TagItem *)&FirstTag);
  703.  
  704.         WriteRequest->IOSer.io_Command = SDCMD_SETPARAMS;
  705.  
  706.         return(DoIO(WriteRequest));
  707.     }
  708.     else
  709.         return(IOERR_SELFTEST);
  710. }
  711.  
  712.     /* GetSerialReadAttributes():
  713.      *
  714.      *    Get the serial read driver parameters.
  715.      */
  716.  
  717. ULONG __stdargs
  718. GetSerialReadAttributes(Tag FirstTag,...)
  719. {
  720.     if(ReadRequest)
  721.         return(GetSerialAttributes(ReadRequest,(struct TagItem *)&FirstTag));
  722.     else
  723.         return(NULL);
  724. }
  725.  
  726.     /* GetSerialWriteAttributes():
  727.      *
  728.      *    Get the serial write driver parameters.
  729.      */
  730.  
  731. ULONG __stdargs
  732. GetSerialWriteAttributes(Tag FirstTag,...)
  733. {
  734.     if(WriteRequest)
  735.         return(GetSerialAttributes(WriteRequest,(struct TagItem *)&FirstTag));
  736.     else
  737.         return(NULL);
  738. }
  739.