home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 2 / goldfish_vol2_cd1.bin / files / comm / net / hydra / source / amiga.c < prev    next >
C/C++ Source or Header  |  1994-01-19  |  40KB  |  1,777 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. #include <intuition/intuitionbase.h>
  16.  
  17. #include <libraries/gadtools.h>
  18.  
  19. #include <graphics/gfxbase.h>
  20.  
  21. #include <utility/date.h>
  22.  
  23. #include <devices/conunit.h>
  24. #include <devices/serial.h>
  25. #include <devices/timer.h>
  26.  
  27. #include <hardware/cia.h>
  28.  
  29. #include <dos/dosextens.h>
  30. #include <dos/filehandler.h>
  31. #include <dos/dosasl.h>
  32.  
  33. #include <exec/memory.h>
  34.  
  35.     /* Correct a nasty bug in the prototypes. */
  36.  
  37. #define CheckIO foo21234
  38.  
  39. #include <clib/intuition_protos.h>
  40. #include <clib/gadtools_protos.h>
  41. #include <clib/graphics_protos.h>
  42. #include <clib/utility_protos.h>
  43. #include <clib/timer_protos.h>
  44. #include <clib/exec_protos.h>
  45. #include <clib/dos_protos.h>
  46. #include <clib/macros.h>
  47.  
  48.     /* Get the CheckIO prototype right. */
  49.  
  50. #undef CheckIO
  51.  
  52. struct IORequest *CheckIO(struct IORequest *);
  53.  
  54. #include "hydracom.h"
  55.  
  56.     /* Serial buffer size. */
  57.  
  58. #define BUFFER_SIZE 8192
  59.  
  60.     /* A handy macro. */
  61.  
  62. #define ClrSignal(s)    SetSignal(0,s)
  63.  
  64.     /* Signal masks. */
  65.  
  66. #define SIG_SERREAD    (1UL << ReadPort -> mp_SigBit)
  67. #define SIG_SERWRITE    (1UL << WritePort -> mp_SigBit)
  68. #define SIG_CONREAD    (1UL << ConsoleReadPort -> mp_SigBit)
  69. #define SIG_TIMER    (1UL << TimePort -> mp_SigBit)
  70. #define SIG_WINDOW    (1UL << LocalWindow -> UserPort -> mp_SigBit)
  71.  
  72.     /* A serial buffer structure. */
  73.  
  74. struct SerialBuffer
  75. {
  76.     struct IOExtSer    *SerialRequest;
  77.     UBYTE        *SerialBuffer,
  78.             *SerialIndex,
  79.             *SerialTop;
  80.     LONG         SerialSize,
  81.              SerialFilled;
  82.     BOOL         IsClone,
  83.              IsBusy;
  84. };
  85.  
  86.     /* Library bases. */
  87.  
  88. struct IntuitionBase    *IntuitionBase;
  89. struct GfxBase        *GfxBase;
  90. struct Library        *GadToolsBase,
  91.             *UtilityBase,
  92.             *TimerBase;
  93.  
  94.     /* Timer data. */
  95.  
  96. struct MsgPort        *TimePort;
  97. struct timerequest    *TimeRequest;
  98.  
  99.     /* Serial data. */
  100.  
  101. struct MsgPort        *ReadPort,
  102.             *WritePort;
  103.  
  104. struct SerialBuffer    *ThisBuffer,
  105.             *NextBuffer,
  106.             *ReadBuffer;
  107.  
  108.     /* Console data. */
  109.  
  110. struct Window        *FileWindow,
  111.             *RemoteWindow,
  112.             *LocalWindow,
  113.             *LogWindow;
  114.  
  115. struct MsgPort        *ConsoleWritePort,
  116.             *ConsoleReadPort;
  117. struct IOStdReq        *ConsoleReadRequest;
  118. UBYTE             ConsoleChar;
  119. BOOL             ConsoleReady = FALSE,
  120.              WindowReady = FALSE;
  121.  
  122. struct IOStdReq        *FileRequest,
  123.             *RemoteRequest,
  124.             *LocalRequest,
  125.             *LogRequest;
  126.  
  127.     /* DOS Data. */
  128.  
  129. struct Process        *ThisProcess;
  130. APTR             OldPtr;
  131.  
  132. struct AnchorPath    *Anchor;
  133. BOOL             AnchorUsed = FALSE;
  134.  
  135.     /* Screen data. */
  136.  
  137. struct Screen        *PublicScreen,
  138.             *Screen;
  139.  
  140.     /* Menu data. */
  141.  
  142. APTR             VisualInfo;
  143. struct Menu        *Menu;
  144.  
  145. struct NewMenu MenuTemplate[] =
  146. {
  147.     { NM_TITLE, "Project",             0 ,    0,    0,    (APTR)0},
  148.     {  NM_ITEM, "Toggle chat",        "C",    0,    0,    (APTR)Alt_C},
  149.     {  NM_ITEM, NM_BARLABEL,         0 ,    0,    0,    (APTR)0},
  150.     {  NM_ITEM, "Hang up",            "H",    0,    0,    (APTR)Alt_H},
  151.     {  NM_ITEM, "Toggle duplex",        "E",    0,    0,    (APTR)Alt_E},
  152.     {  NM_ITEM, "Toggle 7 bits/8 bits",    "B",    0,    0,    (APTR)Alt_B},
  153.     {  NM_ITEM, NM_BARLABEL,         0 ,    0,    0,    (APTR)0},
  154.     {  NM_ITEM, "Start upload",        "U",    0,    0,    (APTR)PgUp},
  155.     {  NM_ITEM, "Start download",        "D",    0,    0,    (APTR)PgDn},
  156.     {  NM_ITEM, NM_BARLABEL,         0 ,    0,    0,    (APTR)0},
  157.     {  NM_ITEM, "Exit HydraCom",        "Q",    0,    0,    (APTR)Alt_X},
  158.     { NM_END,   0,                 0 ,    0,    0,    (APTR)0}
  159. };
  160.  
  161.     /* OpenConsole():
  162.      *
  163.      *    Open a console window.
  164.      */
  165.  
  166. STATIC BOOL __inline
  167. OpenConsole(struct Screen *Screen,LONG Top,LONG Height,STRPTR Title,BOOL Resize,struct Window **WindowPtr,struct IOStdReq **ConsolePtr)
  168. {
  169.     struct Window *Window;
  170.  
  171.     if(Window = OpenWindowTags(NULL,
  172.         WA_Left,        0,
  173.         WA_Top,            Top,
  174.         WA_Width,        Screen -> Width,
  175.         WA_Height,        Height,
  176.         WA_Title,        Title,
  177.         WA_SimpleRefresh,    TRUE,
  178.         WA_DepthGadget,        TRUE,
  179.         WA_DragBar,        TRUE,
  180.         WA_SizeGadget,        Resize,
  181.         WA_SizeBRight,        TRUE,
  182.         WA_CustomScreen,    Screen,
  183.         WA_RMBTrap,        TRUE,
  184.         WA_NewLookMenus,    TRUE,
  185.     TAG_DONE))
  186.     {
  187.         struct IOStdReq *ConsoleRequest;
  188.  
  189.         if(ConsoleRequest = (struct IOStdReq *)CreateIORequest(ConsoleWritePort,sizeof(struct IOStdReq)))
  190.         {
  191.             ConsoleRequest -> io_Data = Window;
  192.  
  193.             if(!OpenDevice("console.device",CONU_CHARMAP,ConsoleRequest,CONFLAG_DEFAULT))
  194.             {
  195.                 WindowLimits(Window,Window -> BorderLeft + 10 * Window -> RPort -> Font -> tf_XSize * 10 + Window -> BorderRight,Window -> BorderTop + 2 * Window -> RPort -> Font -> tf_YSize + Window -> BorderBottom,Screen -> Width,Screen -> Height);
  196.  
  197.                     /* Turn off the cursor. */
  198.  
  199.                 ConPrintf(ConsoleRequest,"\033[0 p");
  200.  
  201.                 *WindowPtr    = Window;
  202.                 *ConsolePtr    = ConsoleRequest;
  203.  
  204.                 return(TRUE);
  205.             }
  206.  
  207.             DeleteIORequest(ConsoleRequest);
  208.         }
  209.  
  210.         CloseWindow(Window);
  211.     }
  212.  
  213.     return(FALSE);
  214. }
  215.  
  216.     /* CloseConsole():
  217.      *
  218.      *    Close a console window.
  219.      */
  220.  
  221. STATIC VOID __inline
  222. CloseConsole(struct Window **WindowPtr,struct IOStdReq **ConsolePtr)
  223. {
  224.     if(*ConsolePtr)
  225.     {
  226.         CloseDevice(*ConsolePtr);
  227.  
  228.         DeleteIORequest(*ConsolePtr);
  229.  
  230.         *ConsolePtr = NULL;
  231.     }
  232.  
  233.     if(*WindowPtr)
  234.     {
  235.         CloseWindow(*WindowPtr);
  236.  
  237.         *WindowPtr = NULL;
  238.     }
  239. }
  240.  
  241.     /* CloneSerialBuffer():
  242.      *
  243.      *    Clone a SerialBuffer structure.
  244.      */
  245.  
  246. STATIC struct SerialBuffer * __regargs
  247. CloneSerialBuffer(struct SerialBuffer *Source,struct MsgPort *MsgPort)
  248. {
  249.     struct SerialBuffer *Buffer;
  250.  
  251.     if(Buffer = (struct SerialBuffer *)AllocVec(sizeof(struct SerialBuffer) + Source -> SerialSize,MEMF_ANY | MEMF_PUBLIC))
  252.     {
  253.         Buffer -> SerialBuffer    = Buffer -> SerialIndex = (UBYTE *)(Buffer + 1);
  254.         Buffer -> SerialFilled    = 0;
  255.         Buffer -> SerialTop    = Buffer -> SerialBuffer + Source -> SerialSize;
  256.         Buffer -> SerialSize    = Source -> SerialSize;
  257.         Buffer -> IsClone    = TRUE;
  258.         Buffer -> IsBusy    = FALSE;
  259.  
  260.         if(Buffer -> SerialRequest = (struct IOExtSer *)AllocVec(sizeof(struct IOExtSer),MEMF_ANY | MEMF_PUBLIC))
  261.         {
  262.             CopyMem(Source -> SerialRequest,Buffer -> SerialRequest,sizeof(struct IOExtSer));
  263.  
  264.             Buffer -> SerialRequest -> IOSer . io_Message . mn_ReplyPort = MsgPort;
  265.  
  266.             return(Buffer);
  267.         }
  268.         else
  269.             cprint("Could not create serial request\n");
  270.  
  271.         FreeVec(Buffer);
  272.     }
  273.     else
  274.         cprint("Could not create serial buffer\n");
  275.  
  276.     return(NULL);
  277. }
  278.  
  279.     /* DeleteSerialBuffer():
  280.      *
  281.      *    Delete a SerialBuffer structure.
  282.      */
  283.  
  284. STATIC VOID __regargs
  285. DeleteSerialBuffer(struct SerialBuffer *Buffer)
  286. {
  287.     if(Buffer)
  288.     {
  289.         if(Buffer -> IsBusy)
  290.         {
  291.             if(!CheckIO(Buffer -> SerialRequest))
  292.                 AbortIO(Buffer -> SerialRequest);
  293.  
  294.             WaitIO(Buffer -> SerialRequest);
  295.         }
  296.  
  297.         if(Buffer -> IsClone)
  298.             FreeVec(Buffer -> SerialRequest);
  299.         else
  300.         {
  301.             CloseDevice(Buffer -> SerialRequest);
  302.  
  303.             DeleteIORequest(Buffer -> SerialRequest);
  304.         }
  305.  
  306.         FreeVec(Buffer);
  307.     }
  308. }
  309.  
  310.     /* CreateSerialBuffer():
  311.      *
  312.      *    Create a serial buffer structure.
  313.      */
  314.  
  315. STATIC struct SerialBuffer * __regargs
  316. CreateSerialBuffer(STRPTR Device,LONG Unit,LONG Size,struct MsgPort *MsgPort)
  317. {
  318.     struct SerialBuffer *Buffer;
  319.  
  320.     if(Buffer = (struct SerialBuffer *)AllocVec(sizeof(struct SerialBuffer) + Size,MEMF_ANY | MEMF_PUBLIC))
  321.     {
  322.         Buffer -> SerialBuffer    = Buffer -> SerialIndex = (UBYTE *)(Buffer + 1);
  323.         Buffer -> SerialFilled    = 0;
  324.         Buffer -> SerialTop    = Buffer -> SerialBuffer + Size;
  325.         Buffer -> SerialSize    = Size;
  326.         Buffer -> IsClone    = FALSE;
  327.         Buffer -> IsBusy    = FALSE;
  328.  
  329.         if(Buffer -> SerialRequest = (struct IOExtSer *)CreateIORequest(MsgPort,sizeof(struct IOExtSer)))
  330.         {
  331.             if(!OpenDevice(Device,Unit,Buffer -> SerialRequest,NULL))
  332.                 return(Buffer);
  333.             else
  334.             {
  335.                 cprint("Could not open \"%s\", unit %d\n",Device,Unit);
  336.  
  337.                 DeleteIORequest(Buffer -> SerialRequest);
  338.             }
  339.         }
  340.         else
  341.             cprint("Could not create serial request\n");
  342.  
  343.         FreeVec(Buffer);
  344.     }
  345.     else
  346.         cprint("Could not create serial buffer\n");
  347.  
  348.     return(NULL);
  349. }
  350.  
  351.     /* OpenAll():
  352.      *
  353.      *    Allocate all the resources required.
  354.      */
  355.  
  356. STATIC BOOL
  357. OpenAll(STRPTR Device,LONG Unit)
  358. {
  359.     LONG Top,Lines,BorderSize,FontSize,ExtraLines,RemainingLines,TotalHeight;
  360.     UWORD Pens = (UWORD)~0;
  361.  
  362.     if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37)))
  363.     {
  364.         cprint("Could not open intuition.library v37\n");
  365.  
  366.         return(FALSE);
  367.     }
  368.  
  369.     if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",37)))
  370.     {
  371.         cprint("Could not open graphics.library v37\n");
  372.  
  373.         return(FALSE);
  374.     }
  375.  
  376.     if(!(GadToolsBase = OpenLibrary("gadtools.library",37)))
  377.     {
  378.         cprint("Could not open gadtools.library v37\n");
  379.  
  380.         return(FALSE);
  381.     }
  382.  
  383.     if(!(UtilityBase = OpenLibrary("utility.library",37)))
  384.     {
  385.         cprint("Could not open utility.library v37\n");
  386.  
  387.         return(FALSE);
  388.     }
  389.  
  390.     if(!(TimePort = CreateMsgPort()))
  391.     {
  392.         cprint("Could not create timer port\n");
  393.  
  394.         return(FALSE);
  395.     }
  396.  
  397.     if(!(TimeRequest = (struct timerequest *)CreateIORequest(TimePort,sizeof(struct timerequest))))
  398.     {
  399.         cprint("Could not create timer request\n");
  400.  
  401.         return(FALSE);
  402.     }
  403.  
  404.     if(OpenDevice(TIMERNAME,UNIT_VBLANK,TimeRequest,NULL))
  405.     {
  406.         cprint("Could not open timer\n");
  407.  
  408.         return(FALSE);
  409.     }
  410.  
  411.     TimerBase = (struct Library *)TimeRequest -> tr_node . io_Device;
  412.  
  413.     if(!(Anchor = (struct AnchorPath *)AllocVec(sizeof(struct AnchorPath) + 512,MEMF_ANY | MEMF_CLEAR)))
  414.     {
  415.         cprint("Could not allocate pattern matching buffe\n");
  416.  
  417.         return(FALSE);
  418.     }
  419.  
  420.     Anchor -> ap_Strlen = 512;
  421.  
  422.     if(!(ReadPort = CreateMsgPort()))
  423.     {
  424.         cprint("Could not create serial read port\n");
  425.  
  426.         return(FALSE);
  427.     }
  428.  
  429.     if(!(WritePort = CreateMsgPort()))
  430.     {
  431.         cprint("Could not create serial write port\n");
  432.  
  433.         return(FALSE);
  434.     }
  435.  
  436.     if(!(ConsoleReadPort = CreateMsgPort()))
  437.     {
  438.         cprint("Could not create console read port\n");
  439.  
  440.         return(FALSE);
  441.     }
  442.  
  443.     if(!(ConsoleWritePort = CreateMsgPort()))
  444.     {
  445.         cprint("Could not create console write port\n");
  446.  
  447.         return(FALSE);
  448.     }
  449.  
  450.     if(!(ConsoleReadRequest = (struct IOStdReq *)AllocVec(sizeof(struct IOStdReq),MEMF_ANY | MEMF_PUBLIC | MEMF_CLEAR)))
  451.     {
  452.         cprint("Could not create console read request\n");
  453.  
  454.         return(FALSE);
  455.     }
  456.  
  457.     if(!(ReadBuffer = CreateSerialBuffer(Device,Unit,BUFFER_SIZE,ReadPort)))
  458.         return(FALSE);
  459.  
  460.     if(!(ThisBuffer = CloneSerialBuffer(ReadBuffer,WritePort)))
  461.         return(FALSE);
  462.  
  463.     if(!(NextBuffer = CloneSerialBuffer(ReadBuffer,WritePort)))
  464.         return(FALSE);
  465.  
  466.     if(!(PublicScreen = LockPubScreen(NULL)))
  467.     {
  468.         cprint("Could not find default public screen\n");
  469.  
  470.         return(FALSE);
  471.     }
  472.  
  473.     if(!(Screen = OpenScreenTags(NULL,
  474.         SA_DisplayID,    GetVPModeID(&PublicScreen -> ViewPort),
  475.         SA_Overscan,    OSCAN_TEXT,
  476.         SA_Depth,    2,
  477.         SA_Title,    PRGNAME " " VERSION " " HC_OS " Ported by Olaf `Olsen' Barthel",
  478.         SA_Behind,    TRUE,
  479.         SA_SysFont,    1,
  480.         SA_Pens,    &Pens,
  481.     TAG_DONE)))
  482.     {
  483.         cprint("Could not open screen\n");
  484.  
  485.         return(FALSE);
  486.     }
  487.  
  488.     if(!(VisualInfo = GetVisualInfo(Screen,TAG_DONE)))
  489.     {
  490.         cprint("Could not obtain screen visual info\n");
  491.  
  492.         return(FALSE);
  493.     }
  494.  
  495.     if(!(Menu = CreateMenus(MenuTemplate,TAG_DONE)))
  496.     {
  497.         cprint("Could not create menus\n");
  498.  
  499.         return(FALSE);
  500.     }
  501.  
  502.     if(!LayoutMenus(Menu,VisualInfo,
  503.         GTMN_TextAttr,        Screen -> Font,
  504.         GTMN_NewLookMenus,    TRUE,
  505.     TAG_DONE))
  506.     {
  507.         cprint("Could not layout menus\n");
  508.  
  509.         return(FALSE);
  510.     }
  511.  
  512.     UnlockPubScreen(NULL,PublicScreen);
  513.  
  514.     PublicScreen = NULL;
  515.  
  516.     Top        = Screen -> BarHeight + 1;
  517.     BorderSize    = Screen -> WBorTop + Screen -> Font -> ta_YSize + 1 + Screen -> WBorBottom;
  518.     FontSize    = GfxBase -> DefaultFont -> tf_YSize;
  519.     TotalHeight    = Screen -> Height - Top;
  520.     Lines        = (TotalHeight - 3 - 4 * BorderSize) / FontSize;
  521.     ExtraLines    = Lines > 25 ? (Lines - 25) / 3 : 0;
  522.     RemainingLines    = Lines > 25 + ExtraLines * 3 ? Lines - (25 + ExtraLines * 3) : 0;
  523.  
  524.     if(Lines < 25)
  525.     {
  526.         cprint("Screen size too small (need at least 25 text lines, can get only %d)\n",Lines);
  527.  
  528.         return(FALSE);
  529.     }
  530.  
  531.     if(!OpenConsole(Screen,Top,BorderSize + (6 + ExtraLines) * FontSize,"Log",TRUE,&LogWindow,&LogRequest))
  532.     {
  533.         cprint("Could not open console window #1\n");
  534.  
  535.         return(FALSE);
  536.     }
  537.  
  538.     TotalHeight    -= LogWindow -> Height + 1;
  539.     Top        += LogWindow -> Height + 1;
  540.  
  541.     if(!OpenConsole(Screen,Top,BorderSize + 3 * FontSize,"File",FALSE,&FileWindow,&FileRequest))
  542.     {
  543.         cprint("Could not open console window #2\n");
  544.  
  545.         return(FALSE);
  546.     }
  547.  
  548.     TotalHeight    -= FileWindow -> Height + 1;
  549.     Top        += FileWindow -> Height + 1;
  550.  
  551.     if(!OpenConsole(Screen,Top,BorderSize + (8 + RemainingLines) * FontSize,"Remote",TRUE,&RemoteWindow,&RemoteRequest))
  552.     {
  553.         cprint("Could not open console window #3\n");
  554.  
  555.         return(FALSE);
  556.     }
  557.  
  558.     TotalHeight    -= RemoteWindow -> Height + 1;
  559.     Top        += RemoteWindow -> Height + 1;
  560.  
  561.     if(!OpenConsole(Screen,Top,TotalHeight,"Local (Press Amiga+X to start/end chat mode)",TRUE,&LocalWindow,&LocalRequest))
  562.     {
  563.         cprint("Could not open console window #4\n");
  564.  
  565.         return(FALSE);
  566.     }
  567.  
  568.     SetMenuStrip(LocalWindow,Menu);
  569.  
  570.     if(!ModifyIDCMP(LocalWindow,IDCMP_MENUPICK))
  571.     {
  572.         cprint("Could not modify IDCMP flags\n");
  573.  
  574.         return(FALSE);
  575.     }
  576.  
  577.     LocalWindow -> Flags &= ~WFLG_RMBTRAP;
  578.  
  579.     CopyMem(LocalRequest,ConsoleReadRequest,sizeof(struct IOStdReq));
  580.  
  581.     ConsoleReadRequest -> io_Message . mn_ReplyPort = ConsoleReadPort;
  582.  
  583.         /* Turn the cursors back on. */
  584.  
  585.     ConPrintf(LocalRequest,"\33[ p");
  586.     ConPrintf(RemoteRequest,"\33[ p");
  587.  
  588.     ConsoleReadRequest -> io_Command    = CMD_READ;
  589.     ConsoleReadRequest -> io_Data        = &ConsoleChar;
  590.     ConsoleReadRequest -> io_Length        = 1;
  591.  
  592.     ClrSignal(SIG_CONREAD);
  593.     SendIO(ConsoleReadRequest);
  594.  
  595.     ThisProcess = (struct Process *)FindTask(NULL);
  596.  
  597.     OldPtr = ThisProcess -> pr_WindowPtr;
  598.  
  599.     ThisProcess -> pr_WindowPtr = (APTR)LocalWindow;
  600.  
  601.     ScreenToFront(Screen);
  602.  
  603.     ActivateWindow(LocalWindow);
  604.  
  605.     return(TRUE);
  606. }
  607.  
  608.     /* CloseAll():
  609.      *
  610.      *    Close all the resources.
  611.      */
  612.  
  613. STATIC VOID
  614. CloseAll(VOID)
  615. {
  616.     if(LocalWindow)
  617.         ClearMenuStrip(LocalWindow);
  618.  
  619.     if(Menu)
  620.         FreeMenus(Menu);
  621.  
  622.     if(VisualInfo)
  623.         FreeVisualInfo(VisualInfo);
  624.  
  625.     if(AnchorUsed)
  626.         MatchEnd(Anchor);
  627.  
  628.     if(Anchor)
  629.         FreeVec(Anchor);
  630.  
  631.     if(ThisProcess)
  632.         ThisProcess -> pr_WindowPtr = OldPtr;
  633.  
  634.     if(ConsoleReadRequest)
  635.     {
  636.         if(ConsoleReadRequest -> io_Device)
  637.         {
  638.             if(!CheckIO(ConsoleReadRequest))
  639.                 AbortIO(ConsoleReadRequest);
  640.  
  641.             WaitIO(ConsoleReadRequest);
  642.         }
  643.  
  644.         FreeVec(ConsoleReadRequest);
  645.     }
  646.  
  647.     CloseConsole(&LocalWindow,&LocalRequest);
  648.     CloseConsole(&RemoteWindow,&RemoteRequest);
  649.     CloseConsole(&FileWindow,&FileRequest);
  650.     CloseConsole(&LogWindow,&LogRequest);
  651.  
  652.     if(Screen)
  653.         CloseScreen(Screen);
  654.  
  655.     if(PublicScreen)
  656.         UnlockPubScreen(NULL,PublicScreen);
  657.  
  658.     DeleteSerialBuffer(NextBuffer);
  659.     DeleteSerialBuffer(ThisBuffer);
  660.     DeleteSerialBuffer(ReadBuffer);
  661.  
  662.     if(ConsoleWritePort)
  663.         DeleteMsgPort(ConsoleWritePort);
  664.  
  665.     if(ConsoleReadPort)
  666.         DeleteMsgPort(ConsoleReadPort);
  667.  
  668.     if(WritePort)
  669.         DeleteMsgPort(WritePort);
  670.  
  671.     if(ReadPort)
  672.         DeleteMsgPort(ReadPort);
  673.  
  674.     if(TimeRequest)
  675.     {
  676.         if(TimeRequest -> tr_node . io_Device)
  677.             CloseDevice(TimeRequest);
  678.  
  679.         DeleteIORequest(TimeRequest);
  680.     }
  681.  
  682.     if(TimePort)
  683.         DeleteMsgPort(TimePort);
  684.  
  685.     if(UtilityBase)
  686.         CloseLibrary(UtilityBase);
  687.  
  688.     if(GadToolsBase)
  689.         CloseLibrary(GadToolsBase);
  690.  
  691.     if(GfxBase)
  692.         CloseLibrary(GfxBase);
  693.  
  694.     if(IntuitionBase)
  695.         CloseLibrary(IntuitionBase);
  696. }
  697.  
  698.     /* ConPutc():
  699.      *
  700.      *    Output a single character.
  701.      */
  702.  
  703. VOID __stdargs
  704. ConPutc(struct IOStdReq *Request,UBYTE Char)
  705. {
  706.     Request -> io_Command    = CMD_WRITE;
  707.     Request -> io_Data    = &Char;
  708.     Request -> io_Length    = 1;
  709.  
  710.     DoIO(Request);
  711. }
  712.  
  713.     /* ConPuts():
  714.      *
  715.      *    Output a string.
  716.      */
  717.  
  718. VOID
  719. ConPuts(struct IOStdReq *Request,STRPTR String)
  720. {
  721.     Request -> io_Command    = CMD_WRITE;
  722.     Request -> io_Data    = String;
  723.     Request -> io_Length    = strlen(String);
  724.  
  725.     DoIO(Request);
  726. }
  727.  
  728.     /* ConPrintf():
  729.      *
  730.      *    Formatted console output.
  731.      */
  732.  
  733. VOID __stdargs
  734. ConPrintf(struct IOStdReq *Request,STRPTR Format,...)
  735. {
  736.     STATIC UBYTE Buffer[512];
  737.  
  738.     va_list VarArgs;
  739.  
  740.     va_start(VarArgs,Format);
  741.     vsprintf(Buffer,Format,VarArgs);
  742.     va_end(VarArgs);
  743.  
  744.     Request -> io_Command    = CMD_WRITE;
  745.     Request -> io_Data    = Buffer;
  746.     Request -> io_Length    = strlen(Buffer);
  747.  
  748.     DoIO(Request);
  749. }
  750.  
  751.     /* ConMove():
  752.      *
  753.      *    Move the cursor to a new position.
  754.      */
  755.  
  756. VOID
  757. ConMove(struct IOStdReq *Request,LONG x,LONG y)
  758. {
  759.     ConPrintf(Request,"\33[%ld;%ldH",y,x);
  760. }
  761.  
  762.     /* ConClear():
  763.      *
  764.      *    Clear the console window.
  765.      */
  766.  
  767. VOID
  768. ConClear(struct IOStdReq *Request)
  769. {
  770.     struct ConUnit *ConUnit = (struct ConUnit *)Request -> io_Device;
  771.     LONG x,y;
  772.  
  773.     x = ConUnit -> cu_XCCP;
  774.     y = ConUnit -> cu_YCCP;
  775.  
  776.     ConPrintf(Request,"\f\33[%ld;%ldH",y,x);
  777. }
  778.  
  779.     /* ConGetKey():
  780.      *
  781.      *    Read a character from a console window.
  782.      */
  783.  
  784. int
  785. ConGetKey()
  786. {
  787.     if(ConsoleReady)
  788.     {
  789.         int Result = ConsoleChar;
  790.  
  791.         ConsoleReady = FALSE;
  792.  
  793.         ConsoleReadRequest -> io_Command    = CMD_READ;
  794.         ConsoleReadRequest -> io_Data        = &ConsoleChar;
  795.         ConsoleReadRequest -> io_Length        = 1;
  796.  
  797.         ClrSignal(SIG_CONREAD);
  798.         SendIO(ConsoleReadRequest);
  799.  
  800.         return(Result);
  801.     }
  802.     else
  803.     {
  804.         int Result = 0;
  805.  
  806.         if(WindowReady)
  807.         {
  808.             struct IntuiMessage *IntuiMessage;
  809.             ULONG MsgClass;
  810.             UWORD MsgCode;
  811.  
  812.             while(IntuiMessage = (struct IntuiMessage *)GetMsg(LocalWindow -> UserPort))
  813.             {
  814.                 MsgClass    = IntuiMessage -> Class;
  815.                 MsgCode        = IntuiMessage -> Code;
  816.  
  817.                 ReplyMsg(IntuiMessage);
  818.  
  819.                 if(MsgClass == IDCMP_MENUPICK)
  820.                 {
  821.                     struct MenuItem *Item;
  822.  
  823.                     while(MsgCode != MENUNULL)
  824.                     {
  825.                         if(Item = ItemAddress(Menu,MsgCode))
  826.                         {
  827.                             if(MENU_USERDATA(Item))
  828.                             {
  829.                                 if(!Result)
  830.                                     Result = (int)MENU_USERDATA(Item);
  831.                             }
  832.  
  833.                             MsgCode = Item -> NextSelect;
  834.                         }
  835.                         else
  836.                             break;
  837.                     }
  838.                 }
  839.             }
  840.  
  841.             WindowReady = FALSE;
  842.         }
  843.  
  844.         return(Result);
  845.     }
  846. }
  847.  
  848.     /* ConScanKey():
  849.      *
  850.      *    Check for a keyboard event.
  851.      */
  852.  
  853. int
  854. ConScanKey()
  855. {
  856.     if(ConsoleReady || WindowReady)
  857.         return(1);
  858.     else
  859.     {
  860.         int Result = 0;
  861.  
  862.         if(CheckSignal(SIG_WINDOW))
  863.         {
  864.             WindowReady = TRUE;
  865.  
  866.             Result = 1;
  867.         }
  868.  
  869.         if(CheckIO(ConsoleReadRequest))
  870.         {
  871.             if(!WaitIO(ConsoleReadRequest))
  872.             {
  873.                 ConsoleReady = TRUE;
  874.  
  875.                 return(1);
  876.             }
  877.             else
  878.             {
  879.                 ConsoleReadRequest -> io_Command    = CMD_READ;
  880.                 ConsoleReadRequest -> io_Data        = &ConsoleChar;
  881.                 ConsoleReadRequest -> io_Length        = 1;
  882.  
  883.                 ClrSignal(SIG_CONREAD);
  884.                 SendIO(ConsoleReadRequest);
  885.             }
  886.         }
  887.  
  888.         return(Result);
  889.     }
  890.  
  891.     return(0);
  892. }
  893.  
  894.     /* dtr_out(byte flag):
  895.      *
  896.      *    If flag == 0 -> drop DTR signal, else set it.
  897.      */
  898.  
  899. VOID
  900. dtr_out(byte flag)
  901. {
  902.     if(!flag)
  903.     {
  904.         if(ThisBuffer -> IsBusy)
  905.         {
  906.             WaitIO(ThisBuffer -> SerialRequest);
  907.     
  908.             ThisBuffer -> IsBusy        = FALSE;
  909.             ThisBuffer -> SerialIndex    = ThisBuffer -> SerialBuffer;
  910.         }
  911.     
  912.         if(ReadBuffer -> IsBusy)
  913.         {
  914.             if(!CheckIO(ReadBuffer -> SerialRequest))
  915.                 AbortIO(ReadBuffer -> SerialRequest);
  916.  
  917.             WaitIO(ReadBuffer -> SerialRequest);
  918.     
  919.             ReadBuffer -> IsBusy        = FALSE;
  920.             ReadBuffer -> SerialFilled    = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  921.             ReadBuffer -> SerialIndex    = ReadBuffer -> SerialBuffer;
  922.     
  923.             ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
  924.     
  925.             DoIO(ReadBuffer -> SerialRequest);
  926.     
  927.             if(ReadBuffer -> SerialRequest -> IOSer . io_Actual)
  928.             {
  929.                 LONG Size = ReadBuffer -> SerialSize - ReadBuffer -> SerialFilled;
  930.     
  931.                 if(Size > 0)
  932.                 {
  933.                     if(Size > ReadBuffer -> SerialRequest -> IOSer . io_Actual)
  934.                         Size = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  935.     
  936.                     ReadBuffer -> SerialRequest -> IOSer . io_Command    = CMD_READ;
  937.                     ReadBuffer -> SerialRequest -> IOSer . io_Data        = ReadBuffer -> SerialBuffer + ReadBuffer -> SerialFilled;
  938.                     ReadBuffer -> SerialRequest -> IOSer . io_Length    = Size;
  939.     
  940.                     DoIO(ReadBuffer -> SerialRequest);
  941.     
  942.                     ReadBuffer -> SerialFilled += ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  943.                 }
  944.             }
  945.         }
  946.  
  947.         CloseDevice(ReadBuffer -> SerialRequest);
  948.  
  949.         TimeRequest -> tr_node . io_Command    = TR_ADDREQUEST;
  950.         TimeRequest -> tr_time . tv_secs    = 1;
  951.         TimeRequest -> tr_time . tv_micro    = 0;
  952.  
  953.         DoIO(TimeRequest);
  954.  
  955.         if(OpenDevice(device,port,ReadBuffer -> SerialRequest,NULL))
  956.         {
  957.             CloseAll();
  958.  
  959.             exit(10);
  960.         }
  961.         else
  962.         {
  963.             ReadBuffer -> SerialRequest -> io_Baud        = ThisBuffer -> SerialRequest -> io_Baud;
  964.             ReadBuffer -> SerialRequest -> io_ReadLen    = ThisBuffer -> SerialRequest -> io_ReadLen;
  965.             ReadBuffer -> SerialRequest -> io_WriteLen    = ThisBuffer -> SerialRequest -> io_WriteLen;
  966.             ReadBuffer -> SerialRequest -> io_SerFlags    = ThisBuffer -> SerialRequest -> io_SerFlags;
  967.  
  968.             ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
  969.  
  970.             DoIO(ReadBuffer -> SerialRequest);
  971.  
  972.             CopyMem(ReadBuffer -> SerialRequest,ThisBuffer -> SerialRequest,sizeof(struct IOExtSer));
  973.  
  974.             ThisBuffer -> SerialRequest -> IOSer . io_Message . mn_ReplyPort = WritePort;
  975.  
  976.             CopyMem(ReadBuffer -> SerialRequest,NextBuffer -> SerialRequest,sizeof(struct IOExtSer));
  977.  
  978.             NextBuffer -> SerialRequest -> IOSer . io_Message . mn_ReplyPort = WritePort;
  979.         }
  980.     }
  981. }
  982.  
  983.     /* com_flow(byte flags):
  984.      *
  985.      *    The bit mask `flags' determines the style(s) of
  986.      *    handshaking:
  987.      *
  988.      *    if (flags & 9) -> enable xON/xOFF software handshaking,
  989.      *    if (flags & 2) -> enable RTS/CTS hardware handshaking
  990.      */
  991.  
  992. VOID
  993. com_flow(byte flags)
  994. {
  995.     if(ThisBuffer -> IsBusy)
  996.     {
  997.         WaitIO(ThisBuffer -> SerialRequest);
  998.  
  999.         ThisBuffer -> IsBusy        = FALSE;
  1000.         ThisBuffer -> SerialIndex    = ThisBuffer -> SerialBuffer;
  1001.     }
  1002.  
  1003.     if(ReadBuffer -> IsBusy)
  1004.     {
  1005.         if(!CheckIO(ReadBuffer -> SerialRequest))
  1006.             AbortIO(ReadBuffer -> SerialRequest);
  1007.  
  1008.         WaitIO(ReadBuffer -> SerialRequest);
  1009.  
  1010.         ReadBuffer -> IsBusy        = FALSE;
  1011.         ReadBuffer -> SerialFilled    = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  1012.         ReadBuffer -> SerialIndex    = ReadBuffer -> SerialBuffer;
  1013.  
  1014.         ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
  1015.  
  1016.         DoIO(ReadBuffer -> SerialRequest);
  1017.  
  1018.         if(ReadBuffer -> SerialRequest -> IOSer . io_Actual)
  1019.         {
  1020.             LONG Size = ReadBuffer -> SerialSize - ReadBuffer -> SerialFilled;
  1021.  
  1022.             if(Size > 0)
  1023.             {
  1024.                 if(Size > ReadBuffer -> SerialRequest -> IOSer . io_Actual)
  1025.                     Size = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  1026.  
  1027.                 ReadBuffer -> SerialRequest -> IOSer . io_Command    = CMD_READ;
  1028.                 ReadBuffer -> SerialRequest -> IOSer . io_Data        = ReadBuffer -> SerialBuffer + ReadBuffer -> SerialFilled;
  1029.                 ReadBuffer -> SerialRequest -> IOSer . io_Length    = Size;
  1030.  
  1031.                 DoIO(ReadBuffer -> SerialRequest);
  1032.  
  1033.                 ReadBuffer -> SerialFilled += ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  1034.             }
  1035.         }
  1036.     }
  1037.  
  1038.     if(flags & 2)
  1039.         ReadBuffer -> SerialRequest -> io_SerFlags |= SERF_7WIRE;
  1040.     else
  1041.         ReadBuffer -> SerialRequest -> io_SerFlags &= ~SERF_7WIRE;
  1042.  
  1043.     if(flags & 9)
  1044.         ReadBuffer -> SerialRequest -> io_SerFlags &= ~SERF_XDISABLED;
  1045.     else
  1046.         ReadBuffer -> SerialRequest -> io_SerFlags |= SERF_XDISABLED;
  1047.  
  1048.     ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
  1049.  
  1050.     DoIO(ReadBuffer -> SerialRequest);
  1051.  
  1052.     ThisBuffer -> SerialRequest -> io_SerFlags = ReadBuffer -> SerialRequest -> io_SerFlags;
  1053.     NextBuffer -> SerialRequest -> io_SerFlags = ReadBuffer -> SerialRequest -> io_SerFlags;
  1054. }
  1055.  
  1056.     /* com_setspeed(word speed):
  1057.      *
  1058.      *    Set the transfer speed (in bits/second).
  1059.      */
  1060.  
  1061. VOID
  1062. com_setspeed(word speed)
  1063. {
  1064.     if(ThisBuffer -> IsBusy)
  1065.     {
  1066.         WaitIO(ThisBuffer -> SerialRequest);
  1067.  
  1068.         ThisBuffer -> IsBusy        = FALSE;
  1069.         ThisBuffer -> SerialIndex    = ThisBuffer -> SerialBuffer;
  1070.     }
  1071.  
  1072.     if(ReadBuffer -> IsBusy)
  1073.     {
  1074.         if(!CheckIO(ReadBuffer -> SerialRequest))
  1075.             AbortIO(ReadBuffer -> SerialRequest);
  1076.  
  1077.         WaitIO(ReadBuffer -> SerialRequest);
  1078.  
  1079.         ReadBuffer -> IsBusy        = FALSE;
  1080.         ReadBuffer -> SerialFilled    = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  1081.         ReadBuffer -> SerialIndex    = ReadBuffer -> SerialBuffer;
  1082.  
  1083.         ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
  1084.  
  1085.         DoIO(ReadBuffer -> SerialRequest);
  1086.  
  1087.         if(ReadBuffer -> SerialRequest -> IOSer . io_Actual)
  1088.         {
  1089.             LONG Size = ReadBuffer -> SerialSize - ReadBuffer -> SerialFilled;
  1090.  
  1091.             if(Size > 0)
  1092.             {
  1093.                 if(Size > ReadBuffer -> SerialRequest -> IOSer . io_Actual)
  1094.                     Size = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  1095.  
  1096.                 ReadBuffer -> SerialRequest -> IOSer . io_Command    = CMD_READ;
  1097.                 ReadBuffer -> SerialRequest -> IOSer . io_Data        = ReadBuffer -> SerialBuffer + ReadBuffer -> SerialFilled;
  1098.                 ReadBuffer -> SerialRequest -> IOSer . io_Length    = Size;
  1099.  
  1100.                 DoIO(ReadBuffer -> SerialRequest);
  1101.  
  1102.                 ReadBuffer -> SerialFilled += ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  1103.             }
  1104.         }
  1105.     }
  1106.  
  1107.     ReadBuffer -> SerialRequest -> io_Baud = speed;
  1108.  
  1109.     if(parity)
  1110.     {
  1111.         ReadBuffer -> SerialRequest -> io_ReadLen = ReadBuffer -> SerialRequest -> io_WriteLen = 7;
  1112.         ReadBuffer -> SerialRequest -> io_SerFlags |= SERF_PARTY_ON;
  1113.     }
  1114.     else
  1115.     {
  1116.         ReadBuffer -> SerialRequest -> io_ReadLen = ReadBuffer -> SerialRequest -> io_WriteLen = 8;
  1117.         ReadBuffer -> SerialRequest -> io_SerFlags &= ~SERF_PARTY_ON;
  1118.     }
  1119.  
  1120.     ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
  1121.  
  1122.     DoIO(ReadBuffer -> SerialRequest);
  1123.  
  1124.     ThisBuffer -> SerialRequest -> io_Baud        = ReadBuffer -> SerialRequest -> io_Baud;
  1125.     ThisBuffer -> SerialRequest -> io_ReadLen    = ReadBuffer -> SerialRequest -> io_ReadLen;
  1126.     ThisBuffer -> SerialRequest -> io_WriteLen    = ReadBuffer -> SerialRequest -> io_WriteLen;
  1127.     ThisBuffer -> SerialRequest -> io_SerFlags    = ReadBuffer -> SerialRequest -> io_SerFlags;
  1128.  
  1129.     NextBuffer -> SerialRequest -> io_Baud        = ReadBuffer -> SerialRequest -> io_Baud;
  1130.     NextBuffer -> SerialRequest -> io_ReadLen    = ReadBuffer -> SerialRequest -> io_ReadLen;
  1131.     NextBuffer -> SerialRequest -> io_WriteLen    = ReadBuffer -> SerialRequest -> io_WriteLen;
  1132.     NextBuffer -> SerialRequest -> io_SerFlags    = ReadBuffer -> SerialRequest -> io_SerFlags;
  1133. }
  1134.  
  1135.     /* com_putblock(byte *s,word len):
  1136.      *
  1137.      *    Send a data block asynchronously.
  1138.      */
  1139.  
  1140. VOID
  1141. com_putblock(byte *s,word len)
  1142. {
  1143.     struct SerialBuffer *Swap = ThisBuffer;
  1144.  
  1145.     if(ThisBuffer -> IsBusy)
  1146.         WaitIO(ThisBuffer -> SerialRequest);
  1147.     else
  1148.     {
  1149.         if(ThisBuffer -> SerialIndex > ThisBuffer -> SerialBuffer)
  1150.         {
  1151.             ThisBuffer -> SerialRequest -> IOSer . io_Command    = CMD_WRITE;
  1152.             ThisBuffer -> SerialRequest -> IOSer . io_Data        = ThisBuffer -> SerialBuffer;
  1153.             ThisBuffer -> SerialRequest -> IOSer . io_Length    = ThisBuffer -> SerialIndex - ThisBuffer -> SerialBuffer;
  1154.  
  1155.             DoIO(ThisBuffer -> SerialRequest);
  1156.         }
  1157.     }
  1158.  
  1159.     ThisBuffer -> IsBusy        = FALSE;
  1160.     ThisBuffer -> SerialIndex    = ThisBuffer -> SerialBuffer;
  1161.  
  1162.     ThisBuffer = NextBuffer;
  1163.     NextBuffer = Swap;
  1164.  
  1165.     if(ThisBuffer -> SerialIndex > ThisBuffer -> SerialBuffer)
  1166.     {
  1167.         ThisBuffer -> SerialRequest -> IOSer . io_Command    = CMD_WRITE;
  1168.         ThisBuffer -> SerialRequest -> IOSer . io_Data        = ThisBuffer -> SerialBuffer;
  1169.         ThisBuffer -> SerialRequest -> IOSer . io_Length    = ThisBuffer -> SerialIndex - ThisBuffer -> SerialBuffer;
  1170.  
  1171.         DoIO(ThisBuffer -> SerialRequest);
  1172.     }
  1173.  
  1174.     ThisBuffer -> IsBusy        = FALSE;
  1175.     ThisBuffer -> SerialIndex    = ThisBuffer -> SerialBuffer;
  1176.  
  1177.     while(len > 2 * ThisBuffer -> SerialSize)
  1178.     {
  1179.         ThisBuffer -> SerialRequest -> IOSer . io_Command    = CMD_WRITE;
  1180.         ThisBuffer -> SerialRequest -> IOSer . io_Data        = s;
  1181.         ThisBuffer -> SerialRequest -> IOSer . io_Length    = ThisBuffer -> SerialSize;
  1182.  
  1183.         s    += ThisBuffer -> SerialSize;
  1184.         len    -= ThisBuffer -> SerialSize;
  1185.  
  1186.         DoIO(ThisBuffer -> SerialRequest);
  1187.     }
  1188.  
  1189.     CopyMem(s,ThisBuffer -> SerialBuffer,MIN(len,ThisBuffer -> SerialSize));
  1190.  
  1191.     ThisBuffer -> IsBusy                    = TRUE;
  1192.     ThisBuffer -> SerialIndex                = ThisBuffer -> SerialBuffer + MIN(len,ThisBuffer -> SerialSize);
  1193.     ThisBuffer -> SerialRequest -> IOSer . io_Command    = CMD_WRITE;
  1194.     ThisBuffer -> SerialRequest -> IOSer . io_Data        = ThisBuffer -> SerialBuffer;
  1195.     ThisBuffer -> SerialRequest -> IOSer . io_Length    = MIN(len,ThisBuffer -> SerialSize);
  1196.  
  1197.     len    -= ThisBuffer -> SerialRequest -> IOSer . io_Length;
  1198.     s    += ThisBuffer -> SerialRequest -> IOSer . io_Length;
  1199.  
  1200.     ClrSignal(SIG_SERWRITE);
  1201.     SendIO(ThisBuffer -> SerialRequest);
  1202.  
  1203.     if(len > 0)
  1204.     {
  1205.         CopyMem(s,NextBuffer -> SerialBuffer,len);
  1206.  
  1207.         NextBuffer -> SerialIndex = NextBuffer -> SerialBuffer + len;
  1208.     }
  1209. }
  1210.  
  1211.     /* breakfunc():
  1212.      *
  1213.      *    Cleanup routine for SAS/C.
  1214.      */
  1215.  
  1216. static int
  1217. breakfunc(void)
  1218. {
  1219.     CloseAll();
  1220.  
  1221.     return(1);
  1222. }
  1223.  
  1224.     /* sys_init(VOID):
  1225.      *
  1226.      *    Initialize this driver implementation.
  1227.      */
  1228.  
  1229. VOID
  1230. sys_init(VOID)
  1231. {
  1232.     if(!OpenAll(device,port))
  1233.     {
  1234.         CloseAll();
  1235.  
  1236.         endprog(2);
  1237.     }
  1238.  
  1239.     onbreak(breakfunc);
  1240. }
  1241.  
  1242.     /* sys_reset(VOID):
  1243.      *
  1244.      *    Perform cleanup for this driver implementation.
  1245.      */
  1246.  
  1247. VOID
  1248. sys_reset(VOID)
  1249. {
  1250.     CloseAll();
  1251. }
  1252.  
  1253.     /* sys_idle(VOID):
  1254.      *
  1255.      *    This routine gets called when the system is idle.
  1256.      *    That's a nice one. We are supposed to call the
  1257.      *    system scheduler, etc.
  1258.      */
  1259.  
  1260. VOID
  1261. sys_idle(VOID)
  1262. {
  1263.     ULONG Signals;
  1264.  
  1265.     if(ReadBuffer -> SerialFilled <= 0 && !ReadBuffer -> IsBusy)
  1266.     {
  1267.         ReadBuffer -> IsBusy                    = TRUE;
  1268.         ReadBuffer -> SerialIndex                = ReadBuffer -> SerialBuffer;
  1269.         ReadBuffer -> SerialRequest -> IOSer . io_Command    = CMD_READ;
  1270.         ReadBuffer -> SerialRequest -> IOSer . io_Data        = ReadBuffer -> SerialBuffer;
  1271.         ReadBuffer -> SerialRequest -> IOSer . io_Length    = 1;
  1272.  
  1273.         ClrSignal(SIG_SERREAD);
  1274.         SendIO(ReadBuffer -> SerialRequest);
  1275.     }
  1276.  
  1277.     TimeRequest -> tr_node . io_Command    = TR_ADDREQUEST;
  1278.     TimeRequest -> tr_time . tv_secs    = 1;
  1279.     TimeRequest -> tr_time . tv_micro    = 0;
  1280.  
  1281.     ClrSignal(SIG_TIMER);
  1282.     SendIO(TimeRequest);
  1283.  
  1284.     Signals = Wait(SIG_SERREAD | SIG_SERWRITE | SIG_CONREAD | SIG_WINDOW | SIG_TIMER);
  1285.  
  1286.     if(!(Signals & SIG_TIMER))
  1287.     {
  1288.         if(!CheckIO(TimeRequest))
  1289.             AbortIO(TimeRequest);
  1290.     }
  1291.  
  1292.     WaitIO(TimeRequest);
  1293.  
  1294.     if(Signals & SIG_SERREAD)
  1295.     {
  1296.         WaitIO(ReadBuffer -> SerialRequest);
  1297.  
  1298.         ReadBuffer -> IsBusy        = FALSE;
  1299.         ReadBuffer -> SerialFilled    = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  1300.         ReadBuffer -> SerialIndex    = ReadBuffer -> SerialBuffer;
  1301.  
  1302.         ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
  1303.  
  1304.         DoIO(ReadBuffer -> SerialRequest);
  1305.  
  1306.         if(ReadBuffer -> SerialRequest -> IOSer . io_Actual)
  1307.         {
  1308.             LONG Size = ReadBuffer -> SerialSize - ReadBuffer -> SerialFilled;
  1309.  
  1310.             if(Size > 0)
  1311.             {
  1312.                 if(Size > ReadBuffer -> SerialRequest -> IOSer . io_Actual)
  1313.                     Size = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  1314.  
  1315.                 ReadBuffer -> SerialRequest -> IOSer . io_Command    = CMD_READ;
  1316.                 ReadBuffer -> SerialRequest -> IOSer . io_Data        = ReadBuffer -> SerialBuffer + ReadBuffer -> SerialFilled;
  1317.                 ReadBuffer -> SerialRequest -> IOSer . io_Length    = Size;
  1318.  
  1319.                 DoIO(ReadBuffer -> SerialRequest);
  1320.  
  1321.                 ReadBuffer -> SerialFilled += ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  1322.             }
  1323.         }
  1324.     }
  1325.  
  1326.     if(Signals & SIG_SERWRITE)
  1327.     {
  1328.         struct SerialBuffer *Swap = ThisBuffer;
  1329.  
  1330.         WaitIO(ThisBuffer -> SerialRequest);
  1331.  
  1332.         ThisBuffer -> IsBusy        = FALSE;
  1333.         ThisBuffer -> SerialIndex    = ThisBuffer -> SerialBuffer;
  1334.  
  1335.         ThisBuffer = NextBuffer;
  1336.         NextBuffer = Swap;
  1337.     }
  1338.  
  1339.     if(Signals & SIG_CONREAD)
  1340.     {
  1341.         WaitIO(ConsoleReadRequest);
  1342.  
  1343.         ConsoleReady = TRUE;
  1344.     }
  1345.  
  1346.     if(Signals & SIG_WINDOW)
  1347.         WindowReady = TRUE;
  1348. }
  1349.  
  1350.     /* com_outfull(VOID):
  1351.      *
  1352.      *    Return number of bytes still to be transferred.
  1353.      */
  1354.  
  1355. int
  1356. com_outfull(VOID)
  1357. {
  1358.     return(ThisBuffer -> SerialIndex - ThisBuffer -> SerialBuffer + NextBuffer -> SerialIndex - NextBuffer -> SerialBuffer);
  1359. }
  1360.  
  1361.     /* carrier(VOID):
  1362.      *
  1363.      *    Return current carrier status.
  1364.      */
  1365.  
  1366. int
  1367. carrier(VOID)
  1368. {
  1369.     if(nocarrier)
  1370.         return(1);
  1371.     else
  1372.     {
  1373.         if(!ThisBuffer -> IsBusy)
  1374.         {
  1375.             ThisBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
  1376.  
  1377.             DoIO(ThisBuffer -> SerialRequest);
  1378.  
  1379.             if(ThisBuffer -> SerialRequest -> io_Status & CIAF_COMCD)
  1380.                 return(0);
  1381.             else
  1382.                 return(1);
  1383.         }
  1384.         else
  1385.         {
  1386.             NextBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
  1387.  
  1388.             DoIO(NextBuffer -> SerialRequest);
  1389.  
  1390.             if(NextBuffer -> SerialRequest -> io_Status & CIAF_COMCD)
  1391.                 return(0);
  1392.             else
  1393.                 return(1);
  1394.         }
  1395.     }
  1396. }
  1397.  
  1398.     /* com_flush(VOID):
  1399.      *
  1400.      *    Make sure all pending data gets written.
  1401.      */
  1402.  
  1403. VOID
  1404. com_flush(VOID)
  1405. {
  1406.     if(ThisBuffer -> IsBusy)
  1407.     {
  1408.         WaitIO(ThisBuffer -> SerialRequest);
  1409.  
  1410.         ThisBuffer -> IsBusy        = FALSE;
  1411.         ThisBuffer -> SerialIndex    = ThisBuffer -> SerialBuffer;
  1412.     }
  1413.  
  1414.     if(NextBuffer -> SerialIndex > NextBuffer -> SerialBuffer)
  1415.     {
  1416.         NextBuffer -> SerialRequest -> IOSer . io_Command    = CMD_WRITE;
  1417.         NextBuffer -> SerialRequest -> IOSer . io_Data        = NextBuffer -> SerialBuffer;
  1418.         NextBuffer -> SerialRequest -> IOSer . io_Length    = NextBuffer -> SerialIndex - NextBuffer -> SerialBuffer;
  1419.  
  1420.         DoIO(NextBuffer -> SerialRequest);
  1421.  
  1422.         NextBuffer -> SerialIndex = NextBuffer -> SerialBuffer;
  1423.     }
  1424. }
  1425.  
  1426.     /* com_putbyte(byte c):
  1427.      *
  1428.      *    Transmit a single byte, queueing it if necessary.
  1429.      */
  1430.  
  1431. VOID
  1432. com_putbyte(byte c)
  1433. {
  1434.     if(ThisBuffer -> IsBusy)
  1435.     {
  1436.         if(NextBuffer -> SerialIndex + 1 >= NextBuffer -> SerialTop)
  1437.         {
  1438.             struct SerialBuffer *Swap = ThisBuffer;
  1439.  
  1440.             WaitIO(ThisBuffer -> SerialRequest);
  1441.  
  1442.             ThisBuffer -> IsBusy        = FALSE;
  1443.             ThisBuffer -> SerialIndex    = ThisBuffer -> SerialBuffer;
  1444.  
  1445.             ThisBuffer = NextBuffer;
  1446.             NextBuffer = Swap;
  1447.  
  1448.             ThisBuffer -> IsBusy                    = TRUE;
  1449.             ThisBuffer -> SerialRequest -> IOSer . io_Command    = CMD_WRITE;
  1450.             ThisBuffer -> SerialRequest -> IOSer . io_Data        = ThisBuffer -> SerialBuffer;
  1451.             ThisBuffer -> SerialRequest -> IOSer . io_Length    = ThisBuffer -> SerialIndex - ThisBuffer -> SerialBuffer;
  1452.  
  1453.             ClrSignal(SIG_SERWRITE);
  1454.             SendIO(ThisBuffer -> SerialRequest);
  1455.         }
  1456.  
  1457.         *NextBuffer -> SerialIndex++ = c;
  1458.     }
  1459.     else
  1460.     {
  1461.         if(ThisBuffer -> SerialIndex + 1 < ThisBuffer -> SerialTop)
  1462.         {
  1463.             *ThisBuffer -> SerialIndex++ = c;
  1464.  
  1465.             ThisBuffer -> IsBusy                    = TRUE;
  1466.             ThisBuffer -> SerialRequest -> IOSer . io_Command    = CMD_WRITE;
  1467.             ThisBuffer -> SerialRequest -> IOSer . io_Data        = ThisBuffer -> SerialBuffer;
  1468.             ThisBuffer -> SerialRequest -> IOSer . io_Length    = 1;
  1469.  
  1470.             ClrSignal(SIG_SERWRITE);
  1471.             SendIO(ThisBuffer -> SerialRequest);
  1472.         }
  1473.         else
  1474.         {
  1475.             ThisBuffer -> IsBusy                    = TRUE;
  1476.             ThisBuffer -> SerialRequest -> IOSer . io_Command    = CMD_WRITE;
  1477.             ThisBuffer -> SerialRequest -> IOSer . io_Data        = ThisBuffer -> SerialBuffer;
  1478.             ThisBuffer -> SerialRequest -> IOSer . io_Length    = ThisBuffer -> SerialIndex - ThisBuffer -> SerialBuffer;
  1479.  
  1480.             ClrSignal(SIG_SERWRITE);
  1481.             SendIO(ThisBuffer -> SerialRequest);
  1482.  
  1483.             *NextBuffer -> SerialIndex++ = c;
  1484.         }
  1485.     }
  1486. }
  1487.  
  1488.     /* com_purge(VOID):
  1489.      *
  1490.      *    Clear the read/write buffers.
  1491.      */
  1492.  
  1493. VOID
  1494. com_purge(VOID)
  1495. {
  1496.     if(ThisBuffer -> IsBusy)
  1497.     {
  1498.         if(!CheckIO(ThisBuffer -> SerialRequest))
  1499.             AbortIO(ThisBuffer -> SerialRequest);
  1500.  
  1501.         WaitIO(ThisBuffer -> SerialRequest);
  1502.     }
  1503.  
  1504.     ThisBuffer -> IsBusy        = FALSE;
  1505.     ThisBuffer -> SerialIndex    = ThisBuffer -> SerialBuffer;
  1506.  
  1507.     NextBuffer -> IsBusy        = FALSE;
  1508.     NextBuffer -> SerialIndex    = NextBuffer -> SerialBuffer;
  1509.  
  1510.     if(ReadBuffer -> IsBusy)
  1511.     {
  1512.         if(!CheckIO(ReadBuffer -> SerialRequest))
  1513.             AbortIO(ReadBuffer -> SerialRequest);
  1514.  
  1515.         WaitIO(ReadBuffer -> SerialRequest);
  1516.     }
  1517.  
  1518.     ReadBuffer -> IsBusy        = FALSE;
  1519.     ReadBuffer -> SerialIndex    = ReadBuffer -> SerialBuffer;
  1520.     ReadBuffer -> SerialFilled    = 0;
  1521.  
  1522.     ThisBuffer -> SerialRequest -> IOSer . io_Command = CMD_CLEAR;
  1523.     DoIO(ThisBuffer -> SerialRequest);
  1524. }
  1525.  
  1526.     /* com_dump(VOID):
  1527.      *
  1528.      *    Wait for asynchronous write request to terminate.
  1529.      */
  1530.  
  1531. VOID
  1532. com_dump(VOID)
  1533. {
  1534.     com_flush();
  1535. }
  1536.  
  1537.     /* com_getbyte(VOID):
  1538.      *
  1539.      *    Read a single byte from the serial line. If not available,
  1540.      *    return EOF.
  1541.      */
  1542.  
  1543. int
  1544. com_getbyte(VOID)
  1545. {
  1546.     int Result;
  1547.  
  1548.     if(ReadBuffer -> SerialFilled <= 0)
  1549.     {
  1550.         if(ReadBuffer -> IsBusy)
  1551.         {
  1552.             if(!CheckIO(ReadBuffer -> SerialRequest))
  1553.                 return(EOF);
  1554.             else
  1555.                 WaitIO(ReadBuffer -> SerialRequest);
  1556.  
  1557.             ReadBuffer -> IsBusy        = FALSE;
  1558.             ReadBuffer -> SerialFilled    = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  1559.             ReadBuffer -> SerialIndex    = ReadBuffer -> SerialBuffer;
  1560.  
  1561.             ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
  1562.  
  1563.             DoIO(ReadBuffer -> SerialRequest);
  1564.  
  1565.             if(ReadBuffer -> SerialRequest -> IOSer . io_Actual)
  1566.             {
  1567.                 LONG Size = ReadBuffer -> SerialSize - ReadBuffer -> SerialFilled;
  1568.  
  1569.                 if(Size > 0)
  1570.                 {
  1571.                     if(Size > ReadBuffer -> SerialRequest -> IOSer . io_Actual)
  1572.                         Size = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  1573.  
  1574.                     ReadBuffer -> SerialRequest -> IOSer . io_Command    = CMD_READ;
  1575.                     ReadBuffer -> SerialRequest -> IOSer . io_Data        = ReadBuffer -> SerialBuffer + ReadBuffer -> SerialFilled;
  1576.                     ReadBuffer -> SerialRequest -> IOSer . io_Length    = Size;
  1577.  
  1578.                     DoIO(ReadBuffer -> SerialRequest);
  1579.  
  1580.                     ReadBuffer -> SerialFilled += ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  1581.                 }
  1582.             }
  1583.         }
  1584.         else
  1585.         {
  1586.             ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
  1587.  
  1588.             DoIO(ReadBuffer -> SerialRequest);
  1589.  
  1590.             if(!ReadBuffer -> SerialRequest -> IOSer . io_Actual)
  1591.                 return(EOF);
  1592.             else
  1593.             {
  1594.                 ReadBuffer -> SerialRequest -> IOSer . io_Command    = CMD_READ;
  1595.                 ReadBuffer -> SerialRequest -> IOSer . io_Data        = ReadBuffer -> SerialBuffer;
  1596.                 ReadBuffer -> SerialRequest -> IOSer . io_Length    = MIN(ReadBuffer -> SerialRequest -> IOSer . io_Actual,ReadBuffer -> SerialSize);
  1597.  
  1598.                 DoIO(ReadBuffer -> SerialRequest);
  1599.  
  1600.                 if(!ReadBuffer -> SerialRequest -> IOSer . io_Actual)
  1601.                     return(EOF);
  1602.                 else
  1603.                 {
  1604.                     ReadBuffer -> SerialFilled    = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
  1605.                     ReadBuffer -> SerialIndex    = ReadBuffer -> SerialBuffer;
  1606.                 }
  1607.             }
  1608.         }
  1609.     }
  1610.  
  1611.     Result = *ReadBuffer -> SerialIndex++;
  1612.  
  1613.     ReadBuffer -> SerialFilled--;
  1614.  
  1615.     if(ReadBuffer -> SerialFilled <= 0)
  1616.     {
  1617.         ReadBuffer -> IsBusy                    = TRUE;
  1618.         ReadBuffer -> SerialIndex                = ReadBuffer -> SerialBuffer;
  1619.  
  1620.         ReadBuffer -> SerialRequest -> IOSer . io_Command    = CMD_READ;
  1621.         ReadBuffer -> SerialRequest -> IOSer . io_Data        = ReadBuffer -> SerialBuffer;
  1622.         ReadBuffer -> SerialRequest -> IOSer . io_Length    = 1;
  1623.  
  1624.         ClrSignal(SIG_SERREAD);
  1625.         SendIO(ReadBuffer -> SerialRequest);
  1626.     }
  1627.  
  1628.     return(Result);
  1629. }
  1630.  
  1631.     /* setstamp(STRPTR Name,LONG Time):
  1632.      *
  1633.      *    Set time/date of a file.
  1634.      */
  1635.  
  1636. VOID
  1637. setstamp(char *Name,long Time)
  1638. {
  1639.         struct tm *t;
  1640.     struct ClockData ClockData;
  1641.     ULONG Seconds;
  1642.     struct DateStamp Date;
  1643.  
  1644.         t = localtime(&Time);
  1645.  
  1646.     ClockData . sec        = t -> tm_sec;
  1647.     ClockData . min        = t -> tm_min;
  1648.     ClockData . hour    = t -> tm_hour;
  1649.     ClockData . mday    = t -> tm_mday;
  1650.     ClockData . month    = t -> tm_mon;
  1651.     ClockData . year    = t -> tm_year + 1900;
  1652.  
  1653.     Seconds = Date2Amiga(&ClockData);
  1654.  
  1655.     Date . ds_Days        = Seconds / (24 * 60 * 60);
  1656.     Date . ds_Minute    = (Seconds % (24 * 60 * 60)) / 60;
  1657.     Date . ds_Tick        = (Seconds % 60) * TICKS_PER_SECOND;
  1658.  
  1659.     SetFileDate(Name,&Date);
  1660. }
  1661.  
  1662.     /* freespace(STRPTR DrivePath):
  1663.      *
  1664.      *    Get free disk space for specified drive.
  1665.      */
  1666.  
  1667. long
  1668. freespace(char *DrivePath)
  1669. {
  1670.     struct DevProc    *DevProc = GetDeviceProc(DrivePath,NULL);
  1671.     struct DosList    *DosList;
  1672.     BOOL         GoodDevice = FALSE;
  1673.     LONG         Size = (LONG)((ULONG)~0 >> 2);
  1674.  
  1675.     if(DosList = LockDosList(LDF_DEVICES | LDF_READ))
  1676.     {
  1677.         while(DosList = NextDosEntry(DosList,LDF_DEVICES))
  1678.         {
  1679.             if(DosList -> dol_Task == DevProc -> dvp_Port)
  1680.             {
  1681.                 struct FileSysStartupMsg *FSSM = (struct FileSysStartupMsg *)BADDR(DosList -> dol_misc . dol_handler . dol_Startup);
  1682.  
  1683.                 if(TypeOfMem(FSSM))
  1684.                 {
  1685.                     struct DosEnvec *DosEnvec = (struct DosEnvec *)BADDR(FSSM -> fssm_Environ);
  1686.                     STRPTR Name = (STRPTR)BADDR(FSSM -> fssm_Device);
  1687.  
  1688.                     if(TypeOfMem(DosEnvec) && TypeOfMem(Name))
  1689.                     {
  1690.                         if(Name[0] > 0 && !Name[(WORD)Name[0] + 1])
  1691.                         {
  1692.                             struct IOStdReq __aligned IORequest;
  1693.  
  1694.                             if(!OpenDevice(Name + 1,FSSM -> fssm_Unit,&IORequest,FSSM -> fssm_Unit))
  1695.                             {
  1696.                                 CloseDevice(&IORequest);
  1697.  
  1698.                                 if(DosEnvec -> de_TableSize > 0 && DosEnvec -> de_LowCyl <= DosEnvec -> de_HighCyl)
  1699.                                     GoodDevice = TRUE;
  1700.                             }
  1701.                         }
  1702.                     }
  1703.                 }
  1704.             }
  1705.         }
  1706.  
  1707.         UnLockDosList(LDF_DEVICES | LDF_READ);
  1708.     }
  1709.  
  1710.     FreeDeviceProc(DevProc);
  1711.  
  1712.     if(GoodDevice)
  1713.     {
  1714.         struct InfoData *InfoData;
  1715.  
  1716.         if(InfoData = (struct InfoData *)AllocVec(sizeof(struct InfoData),MEMF_ANY | MEMF_PUBLIC))
  1717.         {
  1718.             UBYTE NewName[256],*Index;
  1719.             BPTR FileLock;
  1720.  
  1721.             memcpy(NewName,DrivePath,255);
  1722.  
  1723.             NewName[255] = 0;
  1724.  
  1725.             Index = PathPart(NewName);
  1726.  
  1727.             *Index = 0;
  1728.  
  1729.             FileLock = Lock(NewName,ACCESS_READ);
  1730.  
  1731.             if(FileLock)
  1732.             {
  1733.                 if(Info(FileLock,InfoData))
  1734.                     Size = InfoData -> id_BytesPerBlock * (InfoData -> id_NumBlocks - InfoData -> id_NumBlocksUsed);
  1735.  
  1736.                 UnLock(FileLock);
  1737.             }
  1738.  
  1739.             FreeVec(InfoData);
  1740.         }
  1741.     }
  1742.  
  1743.     return(Size);
  1744. }
  1745.  
  1746.     /* ffirst(char *FileSpec):
  1747.      *
  1748.      *    Return name of first file matching the given specs.
  1749.      */
  1750.  
  1751. char *
  1752. ffirst(char *filespec)
  1753. {
  1754.     AnchorUsed = TRUE;
  1755.  
  1756.     if(MatchFirst(filespec,Anchor))
  1757.         return(NULL);
  1758.     else
  1759.         return((char *)Anchor -> ap_Buf);
  1760. }
  1761.  
  1762.     /* fnext(VOID):
  1763.      *
  1764.      *    Return name of next file matching the given specs.
  1765.      */
  1766.  
  1767. char *
  1768. fnext(VOID)
  1769. {
  1770.     AnchorUsed = TRUE;
  1771.  
  1772.     if(MatchNext(Anchor))
  1773.         return(NULL);
  1774.     else
  1775.         return((char *)Anchor -> ap_Buf);
  1776. }
  1777.