home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / ftp.vapor.com / microdot-1 / md1_src_02.lzx / amiga.c < prev    next >
C/C++ Source or Header  |  2014-05-19  |  21KB  |  933 lines

  1. /*
  2. **    Amiga support module for HYDRA protocol sample implementation.
  3. **
  4. **    Written by    Olaf Barthel
  5. **            Brabeckstrasse 35
  6. **            D-30559 Hannover
  7. **
  8. **            eMail: olsen@sourcery.han.de
  9. **
  10. **    Freely distributable.
  11. */
  12.  
  13.     /* System includes. */
  14.  
  15. #define ReadPort (ior.IOSer.io_Message.mn_ReplyPort)
  16. #define WritePort (iow.IOSer.io_Message.mn_ReplyPort)
  17.  
  18. #include <proto/exec.h>
  19. #include <proto/intuition.h>
  20. #include <proto/graphics.h>
  21. #include <proto/gadtools.h>
  22. #include <proto/dos.h>
  23. #include <proto/utility.h>
  24.  
  25. #include <intuition/intuitionbase.h>
  26.  
  27. #include <libraries/gadtools.h>
  28.  
  29. #include <graphics/gfxbase.h>
  30.  
  31. #include <utility/date.h>
  32.  
  33. #include <devices/conunit.h>
  34. #include <devices/serial.h>
  35. #include <devices/timer.h>
  36.  
  37. #include <hardware/cia.h>
  38.  
  39. #include <dos/dosextens.h>
  40. #include <dos/filehandler.h>
  41. #include <dos/dosasl.h>
  42.  
  43. #include <exec/memory.h>
  44.  
  45.     /* Correct a nasty bug in the prototypes. */
  46.  
  47. #define CheckIO foo21234
  48.  
  49. #include <clib/intuition_protos.h>
  50. #include <clib/gadtools_protos.h>
  51. #include <clib/graphics_protos.h>
  52. #include <clib/utility_protos.h>
  53. #include <clib/timer_protos.h>
  54. #include <clib/exec_protos.h>
  55. #include <clib/dos_protos.h>
  56. #include <clib/macros.h>
  57.  
  58.     /* Get the CheckIO prototype right. */
  59.  
  60. #undef CheckIO
  61.  
  62. struct IORequest *CheckIO(struct IORequest *);
  63.  
  64. #include "hydracom.h"
  65.  
  66.     /* Serial buffer size. */
  67.  
  68. #define BUFFER_SIZE 8192
  69.  
  70. #define cprint(s) /**/
  71.  
  72.     /* A handy macro. */
  73.  
  74. #define ClrSignal(s)    SetSignal(0,s)
  75.  
  76.     /* Signal masks. */
  77.  
  78. #define SIG_SERREAD    (1UL << ReadPort -> mp_SigBit)
  79. #define SIG_SERWRITE    (1UL << WritePort -> mp_SigBit)
  80. #define SIG_TIMER    (1UL << TimePort -> mp_SigBit)
  81.  
  82.  
  83.     /* A serial buffer structure. */
  84.  
  85. struct SerialBuffer
  86. {
  87.     struct IOExtSer    *SerialRequest;
  88.     UBYTE        *SerialBuffer,
  89.             *SerialIndex,
  90.             *SerialTop;
  91.     LONG         SerialSize,
  92.              SerialFilled;
  93.     BOOL         IsClone,
  94.              IsBusy;
  95. };
  96.  
  97.     /* Library bases. */
  98.  
  99. struct Library                *TimerBase;
  100.  
  101.     /* Timer data. */
  102.  
  103. struct MsgPort        *TimePort;
  104. struct timerequest    *TimeRequest;
  105.  
  106.     /* Serial data. */
  107.  
  108. struct SerialBuffer    *ThisBuffer,
  109.             *NextBuffer,
  110.             *ReadBuffer;
  111.  
  112.  
  113.     /* CloneSerialBuffer():
  114.      *
  115.      *    Clone a SerialBuffer structure.
  116.      */
  117.  
  118. extern struct IOExtSer ior, iow;
  119.  
  120. STATIC struct SerialBuffer * __regargs
  121. CloneSerialBuffer(struct SerialBuffer *Source,struct MsgPort *MsgPort)
  122. {
  123.     struct SerialBuffer *Buffer;
  124.  
  125.     if(Buffer = (struct SerialBuffer *)AllocVec(sizeof(struct SerialBuffer) + Source -> SerialSize,MEMF_ANY | MEMF_PUBLIC))
  126.     {
  127.         Buffer -> SerialBuffer    = Buffer -> SerialIndex = (UBYTE *)(Buffer + 1);
  128.         Buffer -> SerialFilled    = 0;
  129.         Buffer -> SerialTop    = Buffer -> SerialBuffer + Source -> SerialSize;
  130.         Buffer -> SerialSize    = Source -> SerialSize;
  131.         Buffer -> IsClone    = TRUE;
  132.         Buffer -> IsBusy    = FALSE;
  133.  
  134.         if(Buffer -> SerialRequest = (struct IOExtSer *)AllocVec(sizeof(struct IOExtSer),MEMF_ANY | MEMF_PUBLIC))
  135.         {
  136.             CopyMem(Source -> SerialRequest,Buffer -> SerialRequest,sizeof(struct IOExtSer));
  137.  
  138.             Buffer -> SerialRequest -> IOSer . io_Message . mn_ReplyPort = MsgPort;
  139.  
  140.             return(Buffer);
  141.         }
  142.         else
  143.             cprint("Could not create serial request\n");
  144.  
  145.         FreeVec(Buffer);
  146.     }
  147.     else
  148.         cprint("Could not create serial buffer\n");
  149.  
  150.     return(NULL);
  151. }
  152.  
  153.     /* DeleteSerialBuffer():
  154.      *
  155.      *    Delete a SerialBuffer structure.
  156.      */
  157.  
  158. STATIC VOID __regargs
  159. DeleteSerialBuffer(struct SerialBuffer *Buffer)
  160. {
  161.     if(Buffer)
  162.     {
  163.         if(Buffer -> IsBusy)
  164.         {
  165.             if(!CheckIO(Buffer -> SerialRequest))
  166.                 AbortIO(Buffer -> SerialRequest);
  167.  
  168.             WaitIO(Buffer -> SerialRequest);
  169.         }
  170.  
  171.         if(Buffer -> IsClone)
  172.             FreeVec(Buffer -> SerialRequest);
  173.         else
  174.         {
  175.             /*CloseDevice(Buffer -> SerialRequest);
  176.  
  177.             DeleteIORequest(Buffer -> SerialRequest);*/
  178.         }
  179.  
  180.         FreeVec(Buffer);
  181.     }
  182. }
  183.  
  184.     /* CreateSerialBuffer():
  185.      *
  186.      *    Create a serial buffer structure.
  187.      */
  188.  
  189. STATIC struct SerialBuffer * __regargs
  190. CreateSerialBuffer(LONG Size)
  191. {
  192.     struct SerialBuffer *Buffer;
  193.  
  194.     //message( 0, " ioflags %lx", ior->io_SerFlags );
  195.  
  196.     if(Buffer = (struct SerialBuffer *)AllocVec(sizeof(struct SerialBuffer) + Size,MEMF_ANY | MEMF_PUBLIC))
  197.     {
  198.         Buffer -> SerialBuffer    = Buffer -> SerialIndex = (UBYTE *)(Buffer + 1);
  199.         Buffer -> SerialFilled    = 0;
  200.         Buffer -> SerialTop    = Buffer -> SerialBuffer + Size;
  201.         Buffer -> SerialSize    = Size;
  202.         Buffer -> IsClone    = FALSE;
  203.         Buffer -> IsBusy    = FALSE;
  204.  
  205.         Buffer -> SerialRequest = &ior;
  206.         return( Buffer );
  207.     }
  208.     else
  209.         cprint("Could not create serial buffer\n");
  210.  
  211.     return(NULL);
  212. }
  213.  
  214.     /* OpenAll():
  215.      *
  216.      *    Allocate all the resources required.
  217.      */
  218.  
  219. STATIC BOOL
  220. OpenAll( void )
  221. {
  222.     if(!(TimePort = CreateMsgPort()))
  223.     {
  224.         cprint("Could not create timer port\n");
  225.  
  226.         return(FALSE);
  227.     }
  228.  
  229.     if(!(TimeRequest = (struct timerequest *)CreateIORequest(TimePort,sizeof(struct timerequest))))
  230.     {
  231.         cprint("Could not create timer request\n");
  232.  
  233.         return(FALSE);
  234.     }
  235.  
  236.     if(OpenDevice(TIMERNAME,UNIT_VBLANK,TimeRequest,NULL))
  237.     {
  238.         cprint("Could not open timer\n");
  239.  
  240.         return(FALSE);
  241.     }
  242.  
  243.     TimerBase = (struct Library *)TimeRequest -> tr_node . io_Device;
  244.  
  245.     if(!(ReadBuffer = CreateSerialBuffer(BUFFER_SIZE)))
  246.         return(FALSE);
  247.  
  248.     if(!(ThisBuffer = CloneSerialBuffer(ReadBuffer,WritePort)))
  249.         return(FALSE);
  250.  
  251.     if(!(NextBuffer = CloneSerialBuffer(ReadBuffer,WritePort)))
  252.         return(FALSE);
  253.  
  254.     return(TRUE);
  255. }
  256.  
  257.     /* CloseAll():
  258.      *
  259.      *    Close all the resources.
  260.      */
  261.  
  262. STATIC VOID
  263. CloseAll(VOID)
  264. {
  265.     DeleteSerialBuffer(NextBuffer);
  266.     DeleteSerialBuffer(ThisBuffer);
  267.     DeleteSerialBuffer(ReadBuffer);
  268.  
  269.     if(TimeRequest)
  270.     {
  271.         if(TimeRequest -> tr_node . io_Device)
  272.             CloseDevice(TimeRequest);
  273.  
  274.         DeleteIORequest(TimeRequest);
  275.     }
  276.  
  277.     if(TimePort)
  278.         DeleteMsgPort(TimePort);
  279.  
  280. }
  281.  
  282.     /* ConPutc():
  283.      *
  284.      *    Output a single character.
  285.      */
  286.  
  287. /*VOID __stdargs
  288. ConPutc(struct IOStdReq *Request,UBYTE Char)
  289. {
  290.     Request -> io_Command    = CMD_WRITE;
  291.     Request -> io_Data    = &Char;
  292.     Request -> io_Length    = 1;
  293.  
  294.     DoIO(Request);
  295. }*/
  296.  
  297. VOID
  298. com_putblock(byte *s,word len)
  299. {
  300.     struct SerialBuffer *Swap = ThisBuffer;
  301.  
  302.     //message( 0, " Entering computblock: len %ld", len );
  303.  
  304.     if(ThisBuffer -> IsBusy)
  305.         WaitIO(ThisBuffer -> SerialRequest);
  306.     else
  307.     {
  308.         if(ThisBuffer -> SerialIndex > ThisBuffer -> SerialBuffer)
  309.         {
  310.             ThisBuffer -> SerialRequest -> IOSer . io_Command    = CMD_WRITE;
  311.             ThisBuffer -> SerialRequest -> IOSer . io_Data        = ThisBuffer -> SerialBuffer;
  312.             ThisBuffer -> SerialRequest -> IOSer . io_Length    = ThisBuffer -> SerialIndex - ThisBuffer -> SerialBuffer;
  313.  
  314.             //message( 0, " cpb: before flush (1doio)" );
  315.  
  316.             DoIO(ThisBuffer -> SerialRequest);
  317.         }
  318.     }
  319.  
  320.     //message( 0, " computblock: before bufferswap" );
  321.  
  322.     ThisBuffer -> IsBusy        = FALSE;
  323.     ThisBuffer -> SerialIndex    = ThisBuffer -> SerialBuffer;
  324.  
  325.     ThisBuffer = NextBuffer;
  326.     NextBuffer = Swap;
  327.  
  328.     if(ThisBuffer -> SerialIndex > ThisBuffer -> SerialBuffer)
  329.     {
  330.         ThisBuffer -> SerialRequest -> IOSer . io_Command    = CMD_WRITE;
  331.         ThisBuffer -> SerialRequest -> IOSer . io_Data        = ThisBuffer -> SerialBuffer;
  332.         ThisBuffer -> SerialRequest -> IOSer . io_Length    = ThisBuffer -> SerialIndex - ThisBuffer -> SerialBuffer;
  333.  
  334.         //message( 0, " cpb: before flush (2doio)" );
  335.  
  336.         DoIO(ThisBuffer -> SerialRequest);
  337.     }
  338.  
  339.     ThisBuffer -> IsBusy        = FALSE;
  340.     ThisBuffer -> SerialIndex    = ThisBuffer -> SerialBuffer;
  341.  
  342.     while(len > ( ( 2 * ThisBuffer -> SerialSize ) - 1 ) )
  343.     {
  344.         ThisBuffer -> SerialRequest -> IOSer . io_Command    = CMD_WRITE;
  345.         ThisBuffer -> SerialRequest -> IOSer . io_Data        = s;
  346.         ThisBuffer -> SerialRequest -> IOSer . io_Length    = ThisBuffer -> SerialSize;
  347.  
  348.         s    += ThisBuffer -> SerialSize;
  349.         len    -= ThisBuffer -> SerialSize;
  350.  
  351.         //message( 0, " cpb: writeloop len = %ld", len );
  352.  
  353.         DoIO(ThisBuffer -> SerialRequest);
  354.     }
  355.  
  356.     CopyMem(s,ThisBuffer -> SerialBuffer,MIN(len,ThisBuffer -> SerialSize));
  357.  
  358.     ThisBuffer -> IsBusy                    = TRUE;
  359.     ThisBuffer -> SerialIndex                = ThisBuffer -> SerialBuffer + MIN(len,ThisBuffer -> SerialSize);
  360.     ThisBuffer -> SerialRequest -> IOSer . io_Command    = CMD_WRITE;
  361.     ThisBuffer -> SerialRequest -> IOSer . io_Data        = ThisBuffer -> SerialBuffer;
  362.     ThisBuffer -> SerialRequest -> IOSer . io_Length    = MIN(len,ThisBuffer -> SerialSize);
  363.  
  364.     //message( 0, " cpb: qb1 len = %ld sx = %ld", len, ThisBuffer -> SerialRequest -> IOSer . io_Length );
  365.  
  366.     len    -= ThisBuffer -> SerialRequest -> IOSer . io_Length;
  367.     s    += ThisBuffer -> SerialRequest -> IOSer . io_Length;
  368.  
  369.     ClrSignal(SIG_SERWRITE);
  370.     SendIO(ThisBuffer -> SerialRequest);
  371.  
  372.     if(len > 0)
  373.     {
  374.         CopyMem(s,NextBuffer -> SerialBuffer,len);
  375.  
  376.         NextBuffer -> SerialIndex = NextBuffer -> SerialBuffer + len;
  377.     }
  378.  
  379.     //message( 0, " exit computblock", len );
  380.     
  381. }
  382.  
  383.     /* breakfunc():
  384.      *
  385.      *    Cleanup routine for SAS/C.
  386.      */
  387.  
  388. static int
  389. breakfunc(void)
  390. {
  391.     CloseAll();
  392.  
  393.     return(1);
  394. }
  395.  
  396.     /* sys_init(VOID):
  397.      *
  398.      *    Initialize this driver implementation.
  399.      */
  400.  
  401. VOID
  402. sys_init(VOID)
  403. {
  404.     if(!OpenAll())
  405.     {
  406.         CloseAll();
  407.  
  408.         endprog(2);
  409.     }
  410.  
  411. //    onbreak(breakfunc);
  412. }
  413.  
  414.     /* sys_reset(VOID):
  415.      *
  416.      *    Perform cleanup for this driver implementation.
  417.      */
  418.  
  419. VOID
  420. sys_reset(VOID)
  421. {
  422.     CloseAll();
  423. }
  424.  
  425.     /* sys_idle(VOID):
  426.      *
  427.      *    This routine gets called when the system is idle.
  428.      *    That's a nice one. We are supposed to call the
  429.      *    system scheduler, etc.
  430.      */
  431.  
  432. extern struct Window *twindow;
  433.  
  434. VOID
  435. sys_idle(VOID)
  436. {
  437.     ULONG Signals;
  438.  
  439.     if( ( ReadBuffer -> SerialFilled <= 0 ) && ( !ReadBuffer -> IsBusy ) )
  440.     {
  441.         ReadBuffer -> IsBusy                    = TRUE;
  442.         ReadBuffer -> SerialIndex                = ReadBuffer -> SerialBuffer;
  443.         ReadBuffer -> SerialRequest -> IOSer . io_Command    = CMD_READ;
  444.         ReadBuffer -> SerialRequest -> IOSer . io_Data        = ReadBuffer -> SerialBuffer;
  445.         ReadBuffer -> SerialRequest -> IOSer . io_Length    = 1;
  446.  
  447.         ClrSignal(SIG_SERREAD);
  448.         SendIO(ReadBuffer -> SerialRequest);
  449.     }
  450.  
  451.     TimeRequest -> tr_node . io_Command    = TR_ADDREQUEST;
  452.     TimeRequest -> tr_time . tv_secs    = 1;
  453.     TimeRequest -> tr_time . tv_micro    = 0;
  454.  
  455.     ClrSignal(SIG_TIMER);
  456.     SendIO(TimeRequest);
  457.  
  458.     //message( 0, " Before Wait() in sys_idle t %lx, r %lx, w %lx", SIG_TIMER, SIG_SERREAD, SIG_SERWRITE );
  459.     Signals = Wait(SIG_SERREAD | SIG_SERWRITE | SIG_TIMER | (1L<<twindow->UserPort->mp_SigBit ));
  460.     //message( 0, " After Wait() in sys_idle %lx", Signals );
  461.  
  462.     if(!(Signals & SIG_TIMER))
  463.     {
  464.         if(!CheckIO(TimeRequest))
  465.             AbortIO(TimeRequest);
  466.     }
  467.  
  468.     WaitIO(TimeRequest);
  469.  
  470.     if(Signals & SIG_SERREAD)
  471.     {
  472.         WaitIO(ReadBuffer -> SerialRequest);
  473.  
  474.         ReadBuffer -> IsBusy        = FALSE;
  475.         ReadBuffer -> SerialFilled    = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  476.         ReadBuffer -> SerialIndex    = ReadBuffer -> SerialBuffer;
  477.  
  478.         ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
  479.         DoIO(ReadBuffer -> SerialRequest);
  480.  
  481.         if(ReadBuffer -> SerialRequest -> IOSer . io_Actual)
  482.         {
  483.             LONG Size = ReadBuffer -> SerialSize - ReadBuffer -> SerialFilled;
  484.  
  485.             if(Size > 0)
  486.             {
  487.                 if(Size > ReadBuffer -> SerialRequest -> IOSer . io_Actual)
  488.                     Size = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  489.  
  490.                 ReadBuffer -> SerialRequest -> IOSer . io_Command    = CMD_READ;
  491.                 ReadBuffer -> SerialRequest -> IOSer . io_Data        = ReadBuffer -> SerialBuffer + ReadBuffer -> SerialFilled;
  492.                 ReadBuffer -> SerialRequest -> IOSer . io_Length    = Size;
  493.  
  494.                 DoIO(ReadBuffer -> SerialRequest);
  495.  
  496.                 ReadBuffer -> SerialFilled += ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  497.             }
  498.         }
  499.     }
  500.  
  501.     if(Signals & SIG_SERWRITE)
  502.     {
  503.         struct SerialBuffer *Swap = ThisBuffer;
  504.  
  505.         WaitIO(ThisBuffer -> SerialRequest);
  506.  
  507.         ThisBuffer -> IsBusy        = FALSE;
  508.         ThisBuffer -> SerialIndex    = ThisBuffer -> SerialBuffer;
  509.  
  510.         ThisBuffer = NextBuffer;
  511.         NextBuffer = Swap;
  512.     }
  513.  
  514.     //message( 0, " sys_idle: rbsf %ld", ReadBuffer->SerialFilled );
  515.  
  516. }
  517.  
  518.     /* com_outfull(VOID):
  519.      *
  520.      *    Return number of bytes still to be transferred.
  521.      */
  522.  
  523. int
  524. com_outfull(VOID)
  525. {
  526.     return(ThisBuffer -> SerialIndex - ThisBuffer -> SerialBuffer + NextBuffer -> SerialIndex - NextBuffer -> SerialBuffer);
  527. }
  528.  
  529.     /* carrier(VOID):
  530.      *
  531.      *    Return current carrier status.
  532.      */
  533.  
  534. int
  535. carrier(VOID)
  536. {
  537.     if(nocarrier)
  538.         return(1);
  539.     else
  540.     {
  541.         if(!ThisBuffer -> IsBusy)
  542.         {
  543.             ThisBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
  544.  
  545.             DoIO(ThisBuffer -> SerialRequest);
  546.  
  547.             if(ThisBuffer -> SerialRequest -> io_Status & CIAF_COMCD)
  548.                 return(0);
  549.             else
  550.                 return(1);
  551.         }
  552.         else
  553.         {
  554.             NextBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
  555.  
  556.             DoIO(NextBuffer -> SerialRequest);
  557.  
  558.             if(NextBuffer -> SerialRequest -> io_Status & CIAF_COMCD)
  559.                 return(0);
  560.             else
  561.                 return(1);
  562.         }
  563.     }
  564. }
  565.  
  566.     /* com_flush(VOID):
  567.      *
  568.      *    Make sure all pending data gets written.
  569.      */
  570.  
  571. VOID
  572. com_flush(VOID)
  573. {
  574.     if(ThisBuffer -> IsBusy)
  575.     {
  576.         WaitIO(ThisBuffer -> SerialRequest);
  577.  
  578.         ThisBuffer -> IsBusy        = FALSE;
  579.         ThisBuffer -> SerialIndex    = ThisBuffer -> SerialBuffer;
  580.     }
  581.  
  582.     if(NextBuffer -> SerialIndex > NextBuffer -> SerialBuffer)
  583.     {
  584.         NextBuffer -> SerialRequest -> IOSer . io_Command    = CMD_WRITE;
  585.         NextBuffer -> SerialRequest -> IOSer . io_Data        = NextBuffer -> SerialBuffer;
  586.         NextBuffer -> SerialRequest -> IOSer . io_Length    = NextBuffer -> SerialIndex - NextBuffer -> SerialBuffer;
  587.  
  588.         DoIO(NextBuffer -> SerialRequest);
  589.  
  590.         NextBuffer -> SerialIndex = NextBuffer -> SerialBuffer;
  591.     }
  592. }
  593.  
  594.     /* com_putbyte(byte c):
  595.      *
  596.      *    Transmit a single byte, queueing it if necessary.
  597.      */
  598.  
  599. VOID
  600. com_putbyte(byte c)
  601. {
  602.     //message( 0, " XX com_putbyte; isbusy %ld, thisbuffer %lx", ThisBuffer->IsBusy, ThisBuffer );
  603.  
  604.     if(ThisBuffer -> IsBusy)
  605.     {
  606.         if(NextBuffer -> SerialIndex + 1 >= NextBuffer -> SerialTop)
  607.         {
  608.             struct SerialBuffer *Swap = ThisBuffer;
  609.  
  610.             WaitIO(ThisBuffer -> SerialRequest);
  611.  
  612.             ThisBuffer -> IsBusy        = FALSE;
  613.             ThisBuffer -> SerialIndex    = ThisBuffer -> SerialBuffer;
  614.  
  615.             ThisBuffer = NextBuffer;
  616.             NextBuffer = Swap;
  617.  
  618.             ThisBuffer -> IsBusy                    = TRUE;
  619.             ThisBuffer -> SerialRequest -> IOSer . io_Command    = CMD_WRITE;
  620.             ThisBuffer -> SerialRequest -> IOSer . io_Data        = ThisBuffer -> SerialBuffer;
  621.             ThisBuffer -> SerialRequest -> IOSer . io_Length    = ThisBuffer -> SerialIndex - ThisBuffer -> SerialBuffer;
  622.  
  623.             ClrSignal(SIG_SERWRITE);
  624.             SendIO(ThisBuffer -> SerialRequest);
  625.         }
  626.  
  627.         *NextBuffer -> SerialIndex++ = c;
  628.     }
  629.     else
  630.     {
  631.         if(ThisBuffer -> SerialIndex + 1 < ThisBuffer -> SerialTop)
  632.         {
  633.             *ThisBuffer -> SerialIndex++ = c;
  634.  
  635.             ThisBuffer -> IsBusy                    = TRUE;
  636.             ThisBuffer -> SerialRequest -> IOSer . io_Command    = CMD_WRITE;
  637.             ThisBuffer -> SerialRequest -> IOSer . io_Data        = ThisBuffer -> SerialBuffer;
  638.  
  639. // BUG: LΣnge Falsch berechnet
  640. //            ThisBuffer -> SerialRequest -> IOSer . io_Length    = 1;
  641.  
  642.             ThisBuffer -> SerialRequest -> IOSer . io_Length    = ThisBuffer -> SerialIndex - ThisBuffer -> SerialBuffer;
  643.  
  644.             ClrSignal(SIG_SERWRITE);
  645.             SendIO(ThisBuffer -> SerialRequest);
  646.         }
  647.         else
  648.         {
  649.             ThisBuffer -> IsBusy                    = TRUE;
  650.             ThisBuffer -> SerialRequest -> IOSer . io_Command    = CMD_WRITE;
  651.             ThisBuffer -> SerialRequest -> IOSer . io_Data        = ThisBuffer -> SerialBuffer;
  652.             ThisBuffer -> SerialRequest -> IOSer . io_Length    = ThisBuffer -> SerialIndex - ThisBuffer -> SerialBuffer;
  653.  
  654.             ClrSignal(SIG_SERWRITE);
  655.             SendIO(ThisBuffer -> SerialRequest);
  656.  
  657.             *NextBuffer -> SerialIndex++ = c;
  658.         }
  659.     }
  660. }
  661.  
  662.     /* com_purge(VOID):
  663.      *
  664.      *    Clear the read/write buffers.
  665.      */
  666.  
  667. VOID
  668. com_purge(VOID)
  669. {
  670.     if(ThisBuffer -> IsBusy)
  671.     {
  672.         if(!CheckIO(ThisBuffer -> SerialRequest))
  673.             AbortIO(ThisBuffer -> SerialRequest);
  674.  
  675.         WaitIO(ThisBuffer -> SerialRequest);
  676.     }
  677.  
  678.     ThisBuffer -> IsBusy        = FALSE;
  679.     ThisBuffer -> SerialIndex    = ThisBuffer -> SerialBuffer;
  680.  
  681.     NextBuffer -> IsBusy        = FALSE;
  682.     NextBuffer -> SerialIndex    = NextBuffer -> SerialBuffer;
  683.  
  684.     if(ReadBuffer -> IsBusy)
  685.     {
  686.         if(!CheckIO(ReadBuffer -> SerialRequest))
  687.             AbortIO(ReadBuffer -> SerialRequest);
  688.  
  689.         WaitIO(ReadBuffer -> SerialRequest);
  690.     }
  691.  
  692.     ReadBuffer -> IsBusy        = FALSE;
  693.     ReadBuffer -> SerialIndex    = ReadBuffer -> SerialBuffer;
  694.     ReadBuffer -> SerialFilled    = 0;
  695.  
  696.     ThisBuffer -> SerialRequest -> IOSer . io_Command = CMD_CLEAR;
  697.     DoIO(ThisBuffer -> SerialRequest);
  698. }
  699.  
  700.     /* com_dump(VOID):
  701.      *
  702.      *    Wait for asynchronous write request to terminate.
  703.      */
  704.  
  705. VOID
  706. com_dump(VOID)
  707. {
  708.     com_flush();
  709. }
  710.  
  711.     /* com_getbyte(VOID):
  712.      *
  713.      *    Read a single byte from the serial line. If not available,
  714.      *    return EOF.
  715.      */
  716.  
  717. int
  718. com_getbyte(VOID)
  719. {
  720.     int Result;
  721.  
  722.     if(ReadBuffer -> SerialFilled <= 0)
  723.     {
  724.         if(ReadBuffer -> IsBusy)
  725.         {
  726.             if(!CheckIO(ReadBuffer -> SerialRequest))
  727.             {
  728.                 //message( 0, " CGB: returning EOF" );
  729.                 return(EOF);
  730.             }
  731.             else
  732.                 WaitIO(ReadBuffer -> SerialRequest);
  733.  
  734.             ReadBuffer -> IsBusy        = FALSE;
  735.             ReadBuffer -> SerialFilled    = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  736.             ReadBuffer -> SerialIndex    = ReadBuffer -> SerialBuffer;
  737.  
  738.             ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
  739.             DoIO(ReadBuffer -> SerialRequest);
  740.  
  741.             if(ReadBuffer -> SerialRequest -> IOSer . io_Actual)
  742.             {
  743.                 LONG Size = ReadBuffer -> SerialSize - ReadBuffer -> SerialFilled;
  744.  
  745.                 if(Size > 0)
  746.                 {
  747.                     if(Size > ReadBuffer -> SerialRequest -> IOSer . io_Actual)
  748.                         Size = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  749.  
  750.                     ReadBuffer -> SerialRequest -> IOSer . io_Command    = CMD_READ;
  751.                     ReadBuffer -> SerialRequest -> IOSer . io_Data        = ReadBuffer -> SerialBuffer + ReadBuffer -> SerialFilled;
  752.                     ReadBuffer -> SerialRequest -> IOSer . io_Length    = Size;
  753.  
  754.                     DoIO(ReadBuffer -> SerialRequest);
  755.  
  756.                     ReadBuffer -> SerialFilled += ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  757.                 }
  758.             }
  759.         }
  760.         else
  761.         {
  762.             ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
  763.             DoIO(ReadBuffer -> SerialRequest);
  764.  
  765.             if(!ReadBuffer -> SerialRequest -> IOSer . io_Actual)
  766.             {
  767.                 //message( 0, " CGB: isbusy = FALSE, query = 0, EOF" );
  768.                 return(EOF);
  769.             }
  770.             else
  771.             {
  772.                 ReadBuffer -> SerialRequest -> IOSer . io_Command    = CMD_READ;
  773.                 ReadBuffer -> SerialRequest -> IOSer . io_Data        = ReadBuffer -> SerialBuffer;
  774.                 ReadBuffer -> SerialRequest -> IOSer . io_Length    = MIN(ReadBuffer -> SerialRequest -> IOSer . io_Actual,ReadBuffer -> SerialSize);
  775.  
  776.                 DoIO(ReadBuffer -> SerialRequest);
  777.  
  778.                 if(!ReadBuffer -> SerialRequest -> IOSer . io_Actual)
  779.                 {
  780.                     //message( 0, " CGB: EOF after valid query!!" );
  781.                     return(EOF);
  782.                 }
  783.                 else
  784.                 {
  785.                     ReadBuffer -> SerialFilled    = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  786.                     ReadBuffer -> SerialIndex    = ReadBuffer -> SerialBuffer;
  787.                 }
  788.             }
  789.         }
  790.     }
  791.  
  792. /*    if( !ReadBuffer->SerialFilled )
  793.         message( 0, " CGB: ERROR unexpected serialfilled = " );
  794.  
  795.     if( ReadBuffer->IsBusy )
  796.         message( 0, " CGB: ERROR readbuffer->isbusy " );*/
  797.  
  798.     Result = *ReadBuffer -> SerialIndex++;
  799.     ReadBuffer -> SerialFilled--;
  800.  
  801.     if(ReadBuffer -> SerialFilled <= 0)
  802.     {
  803.         //message( 0, " CGB: queueing new rr" );
  804.  
  805.         ReadBuffer -> IsBusy                    = TRUE;
  806.         ReadBuffer -> SerialIndex                = ReadBuffer -> SerialBuffer;
  807.  
  808.         ReadBuffer -> SerialRequest -> IOSer . io_Command    = CMD_READ;
  809.         ReadBuffer -> SerialRequest -> IOSer . io_Data        = ReadBuffer -> SerialBuffer;
  810.         ReadBuffer -> SerialRequest -> IOSer . io_Length    = 1;
  811.  
  812.         ClrSignal(SIG_SERREAD);
  813.         SendIO(ReadBuffer -> SerialRequest);
  814.     }
  815.  
  816.     return(Result);
  817. }
  818.  
  819.     /* setstamp(STRPTR Name,LONG Time):
  820.      *
  821.      *    Set time/date of a file.
  822.      */
  823.  
  824. VOID
  825. setstamp(char *Name,long Time)
  826. {
  827.         struct tm *t;
  828.     struct ClockData ClockData;
  829.     ULONG Seconds;
  830.     struct DateStamp Date;
  831.  
  832.         t = localtime(&Time);
  833.  
  834.     ClockData . sec        = t -> tm_sec;
  835.     ClockData . min        = t -> tm_min;
  836.     ClockData . hour    = t -> tm_hour;
  837.     ClockData . mday    = t -> tm_mday;
  838.     ClockData . month    = t -> tm_mon;
  839.     ClockData . year    = t -> tm_year + 1900;
  840.  
  841.     Seconds = Date2Amiga(&ClockData);
  842.  
  843.     Date . ds_Days        = Seconds / (24 * 60 * 60);
  844.     Date . ds_Minute    = (Seconds % (24 * 60 * 60)) / 60;
  845.     Date . ds_Tick        = (Seconds % 60) * TICKS_PER_SECOND;
  846.  
  847.     SetFileDate(Name,&Date);
  848. }
  849.  
  850.     /* freespace(STRPTR DrivePath):
  851.      *
  852.      *    Get free disk space for specified drive.
  853.      */
  854.  
  855. long
  856. freespace(char *DrivePath)
  857. {
  858.     struct DevProc    *DevProc = GetDeviceProc(DrivePath,NULL);
  859.     struct DosList    *DosList;
  860.     BOOL         GoodDevice = FALSE;
  861.     LONG         Size = (LONG)((ULONG)~0 >> 2);
  862.  
  863.     if(DosList = LockDosList(LDF_DEVICES | LDF_READ))
  864.     {
  865.         while(DosList = NextDosEntry(DosList,LDF_DEVICES))
  866.         {
  867.             if(DosList -> dol_Task == DevProc -> dvp_Port)
  868.             {
  869.                 struct FileSysStartupMsg *FSSM = (struct FileSysStartupMsg *)BADDR(DosList -> dol_misc . dol_handler . dol_Startup);
  870.  
  871.                 if(TypeOfMem(FSSM))
  872.                 {
  873.                     struct DosEnvec *DosEnvec = (struct DosEnvec *)BADDR(FSSM -> fssm_Environ);
  874.                     STRPTR Name = (STRPTR)BADDR(FSSM -> fssm_Device);
  875.  
  876.                     if(TypeOfMem(DosEnvec) && TypeOfMem(Name))
  877.                     {
  878.                         if(Name[0] > 0 && !Name[(WORD)Name[0] + 1])
  879.                         {
  880.                             struct IOStdReq __aligned IORequest;
  881.  
  882.                             if(!OpenDevice(Name + 1,FSSM -> fssm_Unit,&IORequest,FSSM -> fssm_Unit))
  883.                             {
  884.                                 CloseDevice(&IORequest);
  885.  
  886.                                 if(DosEnvec -> de_TableSize > 0 && DosEnvec -> de_LowCyl <= DosEnvec -> de_HighCyl)
  887.                                     GoodDevice = TRUE;
  888.                             }
  889.                         }
  890.                     }
  891.                 }
  892.             }
  893.         }
  894.  
  895.         UnLockDosList(LDF_DEVICES | LDF_READ);
  896.     }
  897.  
  898.     FreeDeviceProc(DevProc);
  899.  
  900.     if(GoodDevice)
  901.     {
  902.         struct InfoData *InfoData;
  903.  
  904.         if(InfoData = (struct InfoData *)AllocVec(sizeof(struct InfoData),MEMF_ANY | MEMF_PUBLIC))
  905.         {
  906.             UBYTE NewName[256],*Index;
  907.             BPTR FileLock;
  908.  
  909.             memcpy(NewName,DrivePath,255);
  910.  
  911.             NewName[255] = 0;
  912.  
  913.             Index = PathPart(NewName);
  914.  
  915.             *Index = 0;
  916.  
  917.             FileLock = Lock(NewName,ACCESS_READ);
  918.  
  919.             if(FileLock)
  920.             {
  921.                 if(Info(FileLock,InfoData))
  922.                     Size = InfoData -> id_BytesPerBlock * (InfoData -> id_NumBlocks - InfoData -> id_NumBlocksUsed);
  923.  
  924.                 UnLock(FileLock);
  925.             }
  926.  
  927.             FreeVec(InfoData);
  928.         }
  929.     }
  930.  
  931.     return(Size);
  932. }
  933.