home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Creative Computers
/
CreativeComputers.iso
/
shareware
/
telecom
/
term_4.1
/
extras
/
hydracom
/
hydracom-source.lha
/
amiga.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-07-02
|
42KB
|
1,865 lines
/*
** Amiga support module for HYDRA protocol sample implementation.
**
** Written by Olaf Barthel
** Brabeckstrasse 35
** D-30559 Hannover
**
** eMail: olsen@sourcery.han.de
**
** Freely distributable.
*/
/* System includes. */
#include <intuition/intuitionbase.h>
#include <libraries/gadtools.h>
#include <graphics/gfxbase.h>
#include <utility/date.h>
#include <devices/conunit.h>
#include <devices/serial.h>
#include <devices/timer.h>
#include <hardware/cia.h>
#include <dos/dosextens.h>
#include <dos/filehandler.h>
#include <dos/dosasl.h>
#include <exec/memory.h>
/* Correct a nasty bug in the prototypes. */
#define CheckIO foo21234
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/graphics_protos.h>
#include <clib/utility_protos.h>
#include <clib/timer_protos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/macros.h>
/* Get the CheckIO prototype right. */
#undef CheckIO
struct IORequest *CheckIO(struct IORequest *);
#include "Rendezvous.h"
#include "hydracom.h"
/* Serial buffer size. */
#define BUFFER_SIZE 8192
/* A handy macro. */
#define ClrSignal(s) SetSignal(0,s)
/* Signal masks. */
#define SIG_SERREAD (1UL << ReadPort -> mp_SigBit)
#define SIG_SERWRITE (1UL << WritePort -> mp_SigBit)
#define SIG_CONREAD (1UL << ConsoleReadPort -> mp_SigBit)
#define SIG_TIMER (1UL << TimePort -> mp_SigBit)
#define SIG_WINDOW (1UL << LocalWindow -> UserPort -> mp_SigBit)
/* A serial buffer structure. */
struct SerialBuffer
{
struct IOExtSer *SerialRequest;
UBYTE *SerialBuffer,
*SerialIndex,
*SerialTop;
LONG SerialSize,
SerialFilled;
BOOL IsClone,
IsBusy;
};
STATIC struct RendezvousData *RendezvousData;
STATIC struct RendezvousSemaphore *RendezvousSemaphore;
/* Library bases. */
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *GadToolsBase,
*UtilityBase,
*TimerBase;
/* Timer data. */
struct MsgPort *TimePort;
struct timerequest *TimeRequest;
/* Serial data. */
struct MsgPort *ReadPort,
*WritePort;
struct SerialBuffer *ThisBuffer,
*NextBuffer,
*ReadBuffer;
/* Console data. */
struct Window *FileWindow,
*RemoteWindow,
*LocalWindow,
*LogWindow;
struct MsgPort *ConsoleWritePort,
*ConsoleReadPort;
struct IOStdReq *ConsoleReadRequest;
UBYTE ConsoleChar;
BOOL ConsoleReady = FALSE,
WindowReady = FALSE;
struct IOStdReq *FileRequest,
*RemoteRequest,
*LocalRequest,
*LogRequest;
/* DOS Data. */
struct Process *ThisProcess;
APTR OldPtr;
struct AnchorPath *Anchor;
BOOL AnchorUsed = FALSE;
/* Screen data. */
struct Screen *PublicScreen,
*Screen;
/* Menu data. */
APTR VisualInfo;
struct Menu *Menu;
struct NewMenu MenuTemplate[] =
{
{ NM_TITLE, "Project", 0 , 0, 0, (APTR)0},
{ NM_ITEM, "Toggle chat", "C", 0, 0, (APTR)Alt_C},
{ NM_ITEM, NM_BARLABEL, 0 , 0, 0, (APTR)0},
{ NM_ITEM, "Hang up", "H", 0, 0, (APTR)Alt_H},
{ NM_ITEM, "Toggle duplex", "E", 0, 0, (APTR)Alt_E},
{ NM_ITEM, "Toggle 7 bits/8 bits", "B", 0, 0, (APTR)Alt_B},
{ NM_ITEM, NM_BARLABEL, 0 , 0, 0, (APTR)0},
{ NM_ITEM, "Start upload", "U", 0, 0, (APTR)PgUp},
{ NM_ITEM, "Start download", "D", 0, 0, (APTR)PgDn},
{ NM_ITEM, NM_BARLABEL, 0 , 0, 0, (APTR)0},
{ NM_ITEM, "Exit HydraCom", "Q", 0, 0, (APTR)Alt_X},
{ NM_END, 0, 0 , 0, 0, (APTR)0}
};
/* OpenConsole():
*
* Open a console window.
*/
STATIC BOOL __inline
OpenConsole(struct Screen *Screen,LONG Top,LONG Height,STRPTR Title,BOOL Resize,struct Window **WindowPtr,struct IOStdReq **ConsolePtr)
{
struct Window *Window;
if(Window = OpenWindowTags(NULL,
WA_Left, 0,
WA_Top, Top,
WA_Width, Screen -> Width,
WA_Height, Height,
WA_Title, Title,
WA_SimpleRefresh, TRUE,
WA_DepthGadget, TRUE,
WA_DragBar, TRUE,
WA_SizeGadget, Resize,
WA_SizeBRight, TRUE,
WA_CustomScreen, Screen,
WA_RMBTrap, TRUE,
WA_NewLookMenus, TRUE,
TAG_DONE))
{
struct IOStdReq *ConsoleRequest;
if(Window -> RPort -> Font -> tf_Flags & FPF_PROPORTIONAL)
SetFont(Window -> RPort,GfxBase -> DefaultFont);
if(ConsoleRequest = (struct IOStdReq *)CreateIORequest(ConsoleWritePort,sizeof(struct IOStdReq)))
{
ConsoleRequest -> io_Data = Window;
if(!OpenDevice("console.device",CONU_CHARMAP,ConsoleRequest,CONFLAG_DEFAULT))
{
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);
/* Turn off the cursor. */
ConPrintf(ConsoleRequest,"\033[0 p");
*WindowPtr = Window;
*ConsolePtr = ConsoleRequest;
return(TRUE);
}
DeleteIORequest(ConsoleRequest);
}
CloseWindow(Window);
}
return(FALSE);
}
/* CloseConsole():
*
* Close a console window.
*/
STATIC VOID __inline
CloseConsole(struct Window **WindowPtr,struct IOStdReq **ConsolePtr)
{
if(*ConsolePtr)
{
CloseDevice(*ConsolePtr);
DeleteIORequest(*ConsolePtr);
*ConsolePtr = NULL;
}
if(*WindowPtr)
{
CloseWindow(*WindowPtr);
*WindowPtr = NULL;
}
}
/* CloneSerialBuffer():
*
* Clone a SerialBuffer structure.
*/
STATIC struct SerialBuffer * __regargs
CloneSerialBuffer(struct SerialBuffer *Source,struct MsgPort *MsgPort)
{
struct SerialBuffer *Buffer;
if(Buffer = (struct SerialBuffer *)AllocVec(sizeof(struct SerialBuffer) + Source -> SerialSize,MEMF_ANY | MEMF_PUBLIC))
{
Buffer -> SerialBuffer = Buffer -> SerialIndex = (UBYTE *)(Buffer + 1);
Buffer -> SerialFilled = 0;
Buffer -> SerialTop = Buffer -> SerialBuffer + Source -> SerialSize;
Buffer -> SerialSize = Source -> SerialSize;
Buffer -> IsClone = TRUE;
Buffer -> IsBusy = FALSE;
if(Buffer -> SerialRequest = (struct IOExtSer *)AllocVec(sizeof(struct IOExtSer),MEMF_ANY | MEMF_PUBLIC))
{
CopyMem(Source -> SerialRequest,Buffer -> SerialRequest,sizeof(struct IOExtSer));
Buffer -> SerialRequest -> IOSer . io_Message . mn_ReplyPort = MsgPort;
return(Buffer);
}
else
cprint("Could not create serial request\n");
FreeVec(Buffer);
}
else
cprint("Could not create serial buffer\n");
return(NULL);
}
/* DeleteSerialBuffer():
*
* Delete a SerialBuffer structure.
*/
STATIC VOID __regargs
DeleteSerialBuffer(struct SerialBuffer *Buffer)
{
if(Buffer)
{
if(Buffer -> IsBusy)
{
if(!CheckIO(Buffer -> SerialRequest))
AbortIO(Buffer -> SerialRequest);
WaitIO(Buffer -> SerialRequest);
}
if(Buffer -> IsClone)
FreeVec(Buffer -> SerialRequest);
else
{
CloseDevice(Buffer -> SerialRequest);
DeleteIORequest(Buffer -> SerialRequest);
}
FreeVec(Buffer);
}
}
/* CreateSerialBuffer():
*
* Create a serial buffer structure.
*/
STATIC struct SerialBuffer * __regargs
CreateSerialBuffer(STRPTR Device,LONG Unit,LONG Size,struct MsgPort *MsgPort)
{
struct SerialBuffer *Buffer;
if(Buffer = (struct SerialBuffer *)AllocVec(sizeof(struct SerialBuffer) + Size,MEMF_ANY | MEMF_PUBLIC))
{
Buffer -> SerialBuffer = Buffer -> SerialIndex = (UBYTE *)(Buffer + 1);
Buffer -> SerialFilled = 0;
Buffer -> SerialTop = Buffer -> SerialBuffer + Size;
Buffer -> SerialSize = Size;
Buffer -> IsClone = FALSE;
Buffer -> IsBusy = FALSE;
if(Buffer -> SerialRequest = (struct IOExtSer *)CreateIORequest(MsgPort,sizeof(struct IOExtSer)))
{
if(!OpenDevice(Device,Unit,Buffer -> SerialRequest,NULL))
return(Buffer);
else
{
cprint("Could not open \"%s\", unit %d\n",Device,Unit);
DeleteIORequest(Buffer -> SerialRequest);
}
}
else
cprint("Could not create serial request\n");
FreeVec(Buffer);
}
else
cprint("Could not create serial buffer\n");
return(NULL);
}
/* OpenAll():
*
* Allocate all the resources required.
*/
STATIC BOOL
OpenAll(STRPTR Device,LONG Unit)
{
LONG Top,Lines,BorderSize,FontSize,ExtraLines,RemainingLines,TotalHeight;
UWORD Pens = (UWORD)~0;
if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",37)))
{
cprint("Could not open intuition.library v37\n");
return(FALSE);
}
if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",37)))
{
cprint("Could not open graphics.library v37\n");
return(FALSE);
}
if(!(GadToolsBase = OpenLibrary("gadtools.library",37)))
{
cprint("Could not open gadtools.library v37\n");
return(FALSE);
}
if(!(UtilityBase = OpenLibrary("utility.library",37)))
{
cprint("Could not open utility.library v37\n");
return(FALSE);
}
if(!(TimePort = CreateMsgPort()))
{
cprint("Could not create timer port\n");
return(FALSE);
}
if(!(TimeRequest = (struct timerequest *)CreateIORequest(TimePort,sizeof(struct timerequest))))
{
cprint("Could not create timer request\n");
return(FALSE);
}
if(OpenDevice(TIMERNAME,UNIT_VBLANK,TimeRequest,NULL))
{
cprint("Could not open timer\n");
return(FALSE);
}
TimerBase = (struct Library *)TimeRequest -> tr_node . io_Device;
if(!(Anchor = (struct AnchorPath *)AllocVec(sizeof(struct AnchorPath) + 512,MEMF_ANY | MEMF_CLEAR)))
{
cprint("Could not allocate pattern matching buffe\n");
return(FALSE);
}
Anchor -> ap_Strlen = 512;
if(!(ReadPort = CreateMsgPort()))
{
cprint("Could not create serial read port\n");
return(FALSE);
}
if(!(WritePort = CreateMsgPort()))
{
cprint("Could not create serial write port\n");
return(FALSE);
}
Forbid();
if(RendezvousSemaphore = (struct RendezvousSemaphore *)FindSemaphore(Device))
{
ObtainSemaphore(RendezvousSemaphore);
if(!(RendezvousData = (*RendezvousSemaphore -> rs_Login)(ReadPort,WritePort,NULL)))
{
Permit();
ReleaseSemaphore(RendezvousSemaphore);
RendezvousSemaphore = NULL;
cprint("Could not link to `term'\n");
return(FALSE);
}
}
Permit();
if(!(ConsoleReadPort = CreateMsgPort()))
{
cprint("Could not create console read port\n");
return(FALSE);
}
if(!(ConsoleWritePort = CreateMsgPort()))
{
cprint("Could not create console write port\n");
return(FALSE);
}
if(!(ConsoleReadRequest = (struct IOStdReq *)AllocVec(sizeof(struct IOStdReq),MEMF_ANY | MEMF_PUBLIC | MEMF_CLEAR)))
{
cprint("Could not create console read request\n");
return(FALSE);
}
if(!RendezvousData)
{
if(!(ReadBuffer = CreateSerialBuffer(Device,Unit,BUFFER_SIZE,ReadPort)))
return(FALSE);
}
else
{
if(ReadBuffer = (struct SerialBuffer *)AllocVec(sizeof(struct SerialBuffer) + BUFFER_SIZE,MEMF_ANY | MEMF_PUBLIC))
{
ReadBuffer -> SerialBuffer = ReadBuffer -> SerialIndex = (UBYTE *)(ReadBuffer + 1);
ReadBuffer -> SerialFilled = 0;
ReadBuffer -> SerialTop = ReadBuffer -> SerialBuffer + BUFFER_SIZE;
ReadBuffer -> SerialSize = BUFFER_SIZE;
ReadBuffer -> IsClone = TRUE;
ReadBuffer -> IsBusy = FALSE;
ReadBuffer -> SerialRequest = &RendezvousData -> rd_ReadRequest;
}
else
{
cprint("Could not create serial ReadBuffer\n");
return(FALSE);
}
}
if(!(ThisBuffer = CloneSerialBuffer(ReadBuffer,WritePort)))
return(FALSE);
if(!(NextBuffer = CloneSerialBuffer(ReadBuffer,WritePort)))
return(FALSE);
if(!(PublicScreen = LockPubScreen(NULL)))
{
cprint("Could not find default public screen\n");
return(FALSE);
}
if(RendezvousData)
{
if(!(Screen = RendezvousData -> rd_Screen))
Screen = PublicScreen;
}
else
{
if(!(Screen = OpenScreenTags(NULL,
SA_DisplayID, GetVPModeID(&PublicScreen -> ViewPort),
SA_Overscan, OSCAN_TEXT,
SA_Depth, 2,
SA_Title, PRGNAME " " VERSION " " HC_OS " Amiga rev 2, ported by Olaf `Olsen' Barthel",
SA_Behind, TRUE,
SA_SysFont, 1,
SA_Pens, &Pens,
TAG_DONE)))
{
cprint("Could not open screen\n");
return(FALSE);
}
}
if(!(VisualInfo = GetVisualInfo(Screen,TAG_DONE)))
{
cprint("Could not obtain screen visual info\n");
return(FALSE);
}
if(!(Menu = CreateMenus(MenuTemplate,TAG_DONE)))
{
cprint("Could not create menus\n");
return(FALSE);
}
if(!LayoutMenus(Menu,VisualInfo,
GTMN_TextAttr, Screen -> Font,
GTMN_NewLookMenus, TRUE,
TAG_DONE))
{
cprint("Could not layout menus\n");
return(FALSE);
}
Top = Screen -> BarHeight + 1;
BorderSize = Screen -> WBorTop + Screen -> Font -> ta_YSize + 1 + Screen -> WBorBottom;
FontSize = GfxBase -> DefaultFont -> tf_YSize;
TotalHeight = Screen -> Height - Top;
Lines = (TotalHeight - 3 - 4 * BorderSize) / FontSize;
ExtraLines = Lines > 25 ? (Lines - 25) / 3 : 0;
RemainingLines = Lines > 25 + ExtraLines * 3 ? Lines - (25 + ExtraLines * 3) : 0;
if(Lines < 25)
{
cprint("Screen size too small (need at least 25 text lines, can get only %d)\n",Lines);
return(FALSE);
}
if(!OpenConsole(Screen,Top,BorderSize + (6 + ExtraLines) * FontSize,"Log",TRUE,&LogWindow,&LogRequest))
{
cprint("Could not open console window #1\n");
return(FALSE);
}
TotalHeight -= LogWindow -> Height + 1;
Top += LogWindow -> Height + 1;
if(!OpenConsole(Screen,Top,BorderSize + 3 * FontSize,"File",FALSE,&FileWindow,&FileRequest))
{
cprint("Could not open console window #2\n");
return(FALSE);
}
TotalHeight -= FileWindow -> Height + 1;
Top += FileWindow -> Height + 1;
if(!OpenConsole(Screen,Top,BorderSize + (8 + RemainingLines) * FontSize,"Remote",TRUE,&RemoteWindow,&RemoteRequest))
{
cprint("Could not open console window #3\n");
return(FALSE);
}
TotalHeight -= RemoteWindow -> Height + 1;
Top += RemoteWindow -> Height + 1;
if(!OpenConsole(Screen,Top,TotalHeight,"Local (Press Amiga+X to start/end chat mode)",TRUE,&LocalWindow,&LocalRequest))
{
cprint("Could not open console window #4\n");
return(FALSE);
}
SetMenuStrip(LocalWindow,Menu);
if(!ModifyIDCMP(LocalWindow,IDCMP_MENUPICK))
{
cprint("Could not modify IDCMP flags\n");
return(FALSE);
}
LocalWindow -> Flags &= ~WFLG_RMBTRAP;
CopyMem(LocalRequest,ConsoleReadRequest,sizeof(struct IOStdReq));
ConsoleReadRequest -> io_Message . mn_ReplyPort = ConsoleReadPort;
/* Turn the cursors back on. */
ConPrintf(LocalRequest,"\33[ p");
ConPrintf(RemoteRequest,"\33[ p");
ConsoleReadRequest -> io_Command = CMD_READ;
ConsoleReadRequest -> io_Data = &ConsoleChar;
ConsoleReadRequest -> io_Length = 1;
ClrSignal(SIG_CONREAD);
SendIO(ConsoleReadRequest);
ThisProcess = (struct Process *)FindTask(NULL);
OldPtr = ThisProcess -> pr_WindowPtr;
ThisProcess -> pr_WindowPtr = (APTR)LocalWindow;
ScreenToFront(Screen);
ActivateWindow(LocalWindow);
UnlockPubScreen(NULL,PublicScreen);
PublicScreen = NULL;
return(TRUE);
}
/* CloseAll():
*
* Close all the resources.
*/
STATIC VOID
CloseAll(VOID)
{
if(LocalWindow)
ClearMenuStrip(LocalWindow);
if(Menu)
FreeMenus(Menu);
if(VisualInfo)
FreeVisualInfo(VisualInfo);
if(AnchorUsed)
MatchEnd(Anchor);
if(Anchor)
FreeVec(Anchor);
if(ThisProcess)
ThisProcess -> pr_WindowPtr = OldPtr;
if(ConsoleReadRequest)
{
if(ConsoleReadRequest -> io_Device)
{
if(!CheckIO(ConsoleReadRequest))
AbortIO(ConsoleReadRequest);
WaitIO(ConsoleReadRequest);
}
FreeVec(ConsoleReadRequest);
}
CloseConsole(&LocalWindow,&LocalRequest);
CloseConsole(&RemoteWindow,&RemoteRequest);
CloseConsole(&FileWindow,&FileRequest);
CloseConsole(&LogWindow,&LogRequest);
if(!RendezvousData && Screen)
CloseScreen(Screen);
if(PublicScreen)
UnlockPubScreen(NULL,PublicScreen);
DeleteSerialBuffer(NextBuffer);
DeleteSerialBuffer(ThisBuffer);
if(RendezvousData)
{
if(ReadBuffer -> IsBusy)
{
if(!CheckIO(ReadBuffer -> SerialRequest))
AbortIO(ReadBuffer -> SerialRequest);
WaitIO(ReadBuffer -> SerialRequest);
}
FreeVec(ReadBuffer);
}
else
DeleteSerialBuffer(ReadBuffer);
if(ConsoleWritePort)
DeleteMsgPort(ConsoleWritePort);
if(ConsoleReadPort)
DeleteMsgPort(ConsoleReadPort);
if(WritePort)
DeleteMsgPort(WritePort);
if(ReadPort)
DeleteMsgPort(ReadPort);
if(TimeRequest)
{
if(TimeRequest -> tr_node . io_Device)
CloseDevice(TimeRequest);
DeleteIORequest(TimeRequest);
}
if(TimePort)
DeleteMsgPort(TimePort);
if(UtilityBase)
CloseLibrary(UtilityBase);
if(GadToolsBase)
CloseLibrary(GadToolsBase);
if(GfxBase)
CloseLibrary(GfxBase);
if(IntuitionBase)
CloseLibrary(IntuitionBase);
if(RendezvousData)
{
(*RendezvousSemaphore -> rs_Logoff)(RendezvousData);
RendezvousData = NULL;
}
if(RendezvousSemaphore)
{
ReleaseSemaphore(RendezvousSemaphore);
RendezvousSemaphore = NULL;
}
}
/* ConPutc():
*
* Output a single character.
*/
VOID __stdargs
ConPutc(struct IOStdReq *Request,UBYTE Char)
{
Request -> io_Command = CMD_WRITE;
Request -> io_Data = &Char;
Request -> io_Length = 1;
DoIO(Request);
}
/* ConPuts():
*
* Output a string.
*/
VOID
ConPuts(struct IOStdReq *Request,STRPTR String)
{
Request -> io_Command = CMD_WRITE;
Request -> io_Data = String;
Request -> io_Length = strlen(String);
DoIO(Request);
}
/* ConPrintf():
*
* Formatted console output.
*/
VOID __stdargs
ConPrintf(struct IOStdReq *Request,STRPTR Format,...)
{
STATIC UBYTE Buffer[512];
va_list VarArgs;
va_start(VarArgs,Format);
vsprintf(Buffer,Format,VarArgs);
va_end(VarArgs);
Request -> io_Command = CMD_WRITE;
Request -> io_Data = Buffer;
Request -> io_Length = strlen(Buffer);
DoIO(Request);
}
/* ConMove():
*
* Move the cursor to a new position.
*/
VOID
ConMove(struct IOStdReq *Request,LONG x,LONG y)
{
ConPrintf(Request,"\33[%ld;%ldH",y,x);
}
/* ConClear():
*
* Clear the console window.
*/
VOID
ConClear(struct IOStdReq *Request)
{
struct ConUnit *ConUnit = (struct ConUnit *)Request -> io_Device;
LONG x,y;
x = ConUnit -> cu_XCCP;
y = ConUnit -> cu_YCCP;
ConPrintf(Request,"\f\33[%ld;%ldH",y,x);
}
/* ConGetKey():
*
* Read a character from a console window.
*/
int
ConGetKey()
{
if(ConsoleReady)
{
int Result = ConsoleChar;
ConsoleReady = FALSE;
ConsoleReadRequest -> io_Command = CMD_READ;
ConsoleReadRequest -> io_Data = &ConsoleChar;
ConsoleReadRequest -> io_Length = 1;
ClrSignal(SIG_CONREAD);
SendIO(ConsoleReadRequest);
return(Result);
}
else
{
int Result = 0;
if(WindowReady)
{
struct IntuiMessage *IntuiMessage;
ULONG MsgClass;
UWORD MsgCode;
while(IntuiMessage = (struct IntuiMessage *)GetMsg(LocalWindow -> UserPort))
{
MsgClass = IntuiMessage -> Class;
MsgCode = IntuiMessage -> Code;
ReplyMsg(IntuiMessage);
if(MsgClass == IDCMP_MENUPICK)
{
struct MenuItem *Item;
while(MsgCode != MENUNULL)
{
if(Item = ItemAddress(Menu,MsgCode))
{
if(MENU_USERDATA(Item))
{
if(!Result)
Result = (int)MENU_USERDATA(Item);
}
MsgCode = Item -> NextSelect;
}
else
break;
}
}
}
WindowReady = FALSE;
}
return(Result);
}
}
/* ConScanKey():
*
* Check for a keyboard event.
*/
int
ConScanKey()
{
if(ConsoleReady || WindowReady)
return(1);
else
{
int Result = 0;
if(CheckSignal(SIG_WINDOW))
{
WindowReady = TRUE;
Result = 1;
}
if(CheckIO(ConsoleReadRequest))
{
if(!WaitIO(ConsoleReadRequest))
{
ConsoleReady = TRUE;
return(1);
}
else
{
ConsoleReadRequest -> io_Command = CMD_READ;
ConsoleReadRequest -> io_Data = &ConsoleChar;
ConsoleReadRequest -> io_Length = 1;
ClrSignal(SIG_CONREAD);
SendIO(ConsoleReadRequest);
}
}
return(Result);
}
return(0);
}
/* dtr_out(byte flag):
*
* If flag == 0 -> drop DTR signal, else set it.
*/
VOID
dtr_out(byte flag)
{
if(!flag && !RendezvousData)
{
if(ThisBuffer -> IsBusy)
{
WaitIO(ThisBuffer -> SerialRequest);
ThisBuffer -> IsBusy = FALSE;
ThisBuffer -> SerialIndex = ThisBuffer -> SerialBuffer;
}
if(ReadBuffer -> IsBusy)
{
if(!CheckIO(ReadBuffer -> SerialRequest))
AbortIO(ReadBuffer -> SerialRequest);
WaitIO(ReadBuffer -> SerialRequest);
ReadBuffer -> IsBusy = FALSE;
ReadBuffer -> SerialFilled = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
ReadBuffer -> SerialIndex = ReadBuffer -> SerialBuffer;
ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
DoIO(ReadBuffer -> SerialRequest);
if(ReadBuffer -> SerialRequest -> IOSer . io_Actual)
{
LONG Size = ReadBuffer -> SerialSize - ReadBuffer -> SerialFilled;
if(Size > 0)
{
if(Size > ReadBuffer -> SerialRequest -> IOSer . io_Actual)
Size = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
ReadBuffer -> SerialRequest -> IOSer . io_Command = CMD_READ;
ReadBuffer -> SerialRequest -> IOSer . io_Data = ReadBuffer -> SerialBuffer + ReadBuffer -> SerialFilled;
ReadBuffer -> SerialRequest -> IOSer . io_Length = Size;
DoIO(ReadBuffer -> SerialRequest);
ReadBuffer -> SerialFilled += ReadBuffer -> SerialRequest -> IOSer . io_Actual;
}
}
}
CloseDevice(ReadBuffer -> SerialRequest);
TimeRequest -> tr_node . io_Command = TR_ADDREQUEST;
TimeRequest -> tr_time . tv_secs = 1;
TimeRequest -> tr_time . tv_micro = 0;
DoIO(TimeRequest);
if(OpenDevice(device,port,ReadBuffer -> SerialRequest,NULL))
{
CloseAll();
exit(10);
}
else
{
ReadBuffer -> SerialRequest -> io_Baud = ThisBuffer -> SerialRequest -> io_Baud;
ReadBuffer -> SerialRequest -> io_ReadLen = ThisBuffer -> SerialRequest -> io_ReadLen;
ReadBuffer -> SerialRequest -> io_WriteLen = ThisBuffer -> SerialRequest -> io_WriteLen;
ReadBuffer -> SerialRequest -> io_SerFlags = ThisBuffer -> SerialRequest -> io_SerFlags;
ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
DoIO(ReadBuffer -> SerialRequest);
CopyMem(ReadBuffer -> SerialRequest,ThisBuffer -> SerialRequest,sizeof(struct IOExtSer));
ThisBuffer -> SerialRequest -> IOSer . io_Message . mn_ReplyPort = WritePort;
CopyMem(ReadBuffer -> SerialRequest,NextBuffer -> SerialRequest,sizeof(struct IOExtSer));
NextBuffer -> SerialRequest -> IOSer . io_Message . mn_ReplyPort = WritePort;
}
}
}
/* com_flow(byte flags):
*
* The bit mask `flags' determines the style(s) of
* handshaking:
*
* if (flags & 9) -> enable xON/xOFF software handshaking,
* if (flags & 2) -> enable RTS/CTS hardware handshaking
*/
VOID
com_flow(byte flags)
{
if(ThisBuffer -> IsBusy)
{
WaitIO(ThisBuffer -> SerialRequest);
ThisBuffer -> IsBusy = FALSE;
ThisBuffer -> SerialIndex = ThisBuffer -> SerialBuffer;
}
if(ReadBuffer -> IsBusy)
{
if(!CheckIO(ReadBuffer -> SerialRequest))
AbortIO(ReadBuffer -> SerialRequest);
WaitIO(ReadBuffer -> SerialRequest);
ReadBuffer -> IsBusy = FALSE;
ReadBuffer -> SerialFilled = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
ReadBuffer -> SerialIndex = ReadBuffer -> SerialBuffer;
ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
DoIO(ReadBuffer -> SerialRequest);
if(ReadBuffer -> SerialRequest -> IOSer . io_Actual)
{
LONG Size = ReadBuffer -> SerialSize - ReadBuffer -> SerialFilled;
if(Size > 0)
{
if(Size > ReadBuffer -> SerialRequest -> IOSer . io_Actual)
Size = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
ReadBuffer -> SerialRequest -> IOSer . io_Command = CMD_READ;
ReadBuffer -> SerialRequest -> IOSer . io_Data = ReadBuffer -> SerialBuffer + ReadBuffer -> SerialFilled;
ReadBuffer -> SerialRequest -> IOSer . io_Length = Size;
DoIO(ReadBuffer -> SerialRequest);
ReadBuffer -> SerialFilled += ReadBuffer -> SerialRequest -> IOSer . io_Actual;
}
}
}
if(flags & 2)
ReadBuffer -> SerialRequest -> io_SerFlags |= SERF_7WIRE;
else
ReadBuffer -> SerialRequest -> io_SerFlags &= ~SERF_7WIRE;
if(flags & 9)
ReadBuffer -> SerialRequest -> io_SerFlags &= ~SERF_XDISABLED;
else
ReadBuffer -> SerialRequest -> io_SerFlags |= SERF_XDISABLED;
ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
DoIO(ReadBuffer -> SerialRequest);
ThisBuffer -> SerialRequest -> io_SerFlags = ReadBuffer -> SerialRequest -> io_SerFlags;
NextBuffer -> SerialRequest -> io_SerFlags = ReadBuffer -> SerialRequest -> io_SerFlags;
}
/* com_setspeed(word speed):
*
* Set the transfer speed (in bits/second).
*/
VOID
com_setspeed(word speed)
{
if(ThisBuffer -> IsBusy)
{
WaitIO(ThisBuffer -> SerialRequest);
ThisBuffer -> IsBusy = FALSE;
ThisBuffer -> SerialIndex = ThisBuffer -> SerialBuffer;
}
if(ReadBuffer -> IsBusy)
{
if(!CheckIO(ReadBuffer -> SerialRequest))
AbortIO(ReadBuffer -> SerialRequest);
WaitIO(ReadBuffer -> SerialRequest);
ReadBuffer -> IsBusy = FALSE;
ReadBuffer -> SerialFilled = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
ReadBuffer -> SerialIndex = ReadBuffer -> SerialBuffer;
ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
DoIO(ReadBuffer -> SerialRequest);
if(ReadBuffer -> SerialRequest -> IOSer . io_Actual)
{
LONG Size = ReadBuffer -> SerialSize - ReadBuffer -> SerialFilled;
if(Size > 0)
{
if(Size > ReadBuffer -> SerialRequest -> IOSer . io_Actual)
Size = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
ReadBuffer -> SerialRequest -> IOSer . io_Command = CMD_READ;
ReadBuffer -> SerialRequest -> IOSer . io_Data = ReadBuffer -> SerialBuffer + ReadBuffer -> SerialFilled;
ReadBuffer -> SerialRequest -> IOSer . io_Length = Size;
DoIO(ReadBuffer -> SerialRequest);
ReadBuffer -> SerialFilled += ReadBuffer -> SerialRequest -> IOSer . io_Actual;
}
}
}
ReadBuffer -> SerialRequest -> io_Baud = speed;
if(parity)
{
ReadBuffer -> SerialRequest -> io_ReadLen = ReadBuffer -> SerialRequest -> io_WriteLen = 7;
ReadBuffer -> SerialRequest -> io_SerFlags |= SERF_PARTY_ON;
}
else
{
ReadBuffer -> SerialRequest -> io_ReadLen = ReadBuffer -> SerialRequest -> io_WriteLen = 8;
ReadBuffer -> SerialRequest -> io_SerFlags &= ~SERF_PARTY_ON;
}
ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_SETPARAMS;
DoIO(ReadBuffer -> SerialRequest);
ThisBuffer -> SerialRequest -> io_Baud = ReadBuffer -> SerialRequest -> io_Baud;
ThisBuffer -> SerialRequest -> io_ReadLen = ReadBuffer -> SerialRequest -> io_ReadLen;
ThisBuffer -> SerialRequest -> io_WriteLen = ReadBuffer -> SerialRequest -> io_WriteLen;
ThisBuffer -> SerialRequest -> io_SerFlags = ReadBuffer -> SerialRequest -> io_SerFlags;
NextBuffer -> SerialRequest -> io_Baud = ReadBuffer -> SerialRequest -> io_Baud;
NextBuffer -> SerialRequest -> io_ReadLen = ReadBuffer -> SerialRequest -> io_ReadLen;
NextBuffer -> SerialRequest -> io_WriteLen = ReadBuffer -> SerialRequest -> io_WriteLen;
NextBuffer -> SerialRequest -> io_SerFlags = ReadBuffer -> SerialRequest -> io_SerFlags;
}
/* com_putblock(byte *s,word len):
*
* Send a data block asynchronously.
*/
VOID
com_putblock(byte *s,word len)
{
struct SerialBuffer *Swap = ThisBuffer;
if(ThisBuffer -> IsBusy)
WaitIO(ThisBuffer -> SerialRequest);
else
{
if(ThisBuffer -> SerialIndex > ThisBuffer -> SerialBuffer)
{
ThisBuffer -> SerialRequest -> IOSer . io_Command = CMD_WRITE;
ThisBuffer -> SerialRequest -> IOSer . io_Data = ThisBuffer -> SerialBuffer;
ThisBuffer -> SerialRequest -> IOSer . io_Length = ThisBuffer -> SerialIndex - ThisBuffer -> SerialBuffer;
DoIO(ThisBuffer -> SerialRequest);
}
}
ThisBuffer -> IsBusy = FALSE;
ThisBuffer -> SerialIndex = ThisBuffer -> SerialBuffer;
ThisBuffer = NextBuffer;
NextBuffer = Swap;
if(ThisBuffer -> SerialIndex > ThisBuffer -> SerialBuffer)
{
ThisBuffer -> SerialRequest -> IOSer . io_Command = CMD_WRITE;
ThisBuffer -> SerialRequest -> IOSer . io_Data = ThisBuffer -> SerialBuffer;
ThisBuffer -> SerialRequest -> IOSer . io_Length = ThisBuffer -> SerialIndex - ThisBuffer -> SerialBuffer;
DoIO(ThisBuffer -> SerialRequest);
}
ThisBuffer -> IsBusy = FALSE;
ThisBuffer -> SerialIndex = ThisBuffer -> SerialBuffer;
while(len > 2 * ThisBuffer -> SerialSize)
{
ThisBuffer -> SerialRequest -> IOSer . io_Command = CMD_WRITE;
ThisBuffer -> SerialRequest -> IOSer . io_Data = s;
ThisBuffer -> SerialRequest -> IOSer . io_Length = ThisBuffer -> SerialSize;
s += ThisBuffer -> SerialSize;
len -= ThisBuffer -> SerialSize;
DoIO(ThisBuffer -> SerialRequest);
}
CopyMem(s,ThisBuffer -> SerialBuffer,MIN(len,ThisBuffer -> SerialSize));
ThisBuffer -> IsBusy = TRUE;
ThisBuffer -> SerialIndex = ThisBuffer -> SerialBuffer + MIN(len,ThisBuffer -> SerialSize);
ThisBuffer -> SerialRequest -> IOSer . io_Command = CMD_WRITE;
ThisBuffer -> SerialRequest -> IOSer . io_Data = ThisBuffer -> SerialBuffer;
ThisBuffer -> SerialRequest -> IOSer . io_Length = MIN(len,ThisBuffer -> SerialSize);
len -= ThisBuffer -> SerialRequest -> IOSer . io_Length;
s += ThisBuffer -> SerialRequest -> IOSer . io_Length;
ClrSignal(SIG_SERWRITE);
SendIO(ThisBuffer -> SerialRequest);
if(len > 0)
{
CopyMem(s,NextBuffer -> SerialBuffer,len);
NextBuffer -> SerialIndex = NextBuffer -> SerialBuffer + len;
}
}
/* breakfunc():
*
* Cleanup routine for SAS/C.
*/
static int
breakfunc(void)
{
CloseAll();
return(1);
}
/* sys_init(VOID):
*
* Initialize this driver implementation.
*/
VOID
sys_init(VOID)
{
if(!OpenAll(device,port))
{
CloseAll();
endprog(2);
}
onbreak(breakfunc);
}
/* sys_reset(VOID):
*
* Perform cleanup for this driver implementation.
*/
VOID
sys_reset(VOID)
{
CloseAll();
}
/* sys_idle(VOID):
*
* This routine gets called when the system is idle.
* That's a nice one. We are supposed to call the
* system scheduler, etc.
*/
VOID
sys_idle(VOID)
{
ULONG Signals;
if(ReadBuffer -> SerialFilled <= 0 && !ReadBuffer -> IsBusy)
{
ReadBuffer -> IsBusy = TRUE;
ReadBuffer -> SerialIndex = ReadBuffer -> SerialBuffer;
ReadBuffer -> SerialRequest -> IOSer . io_Command = CMD_READ;
ReadBuffer -> SerialRequest -> IOSer . io_Data = ReadBuffer -> SerialBuffer;
ReadBuffer -> SerialRequest -> IOSer . io_Length = 1;
ClrSignal(SIG_SERREAD);
SendIO(ReadBuffer -> SerialRequest);
}
TimeRequest -> tr_node . io_Command = TR_ADDREQUEST;
TimeRequest -> tr_time . tv_secs = 1;
TimeRequest -> tr_time . tv_micro = 0;
ClrSignal(SIG_TIMER);
SendIO(TimeRequest);
Signals = Wait(SIG_SERREAD | SIG_SERWRITE | SIG_CONREAD | SIG_WINDOW | SIG_TIMER);
if(!(Signals & SIG_TIMER))
{
if(!CheckIO(TimeRequest))
AbortIO(TimeRequest);
}
WaitIO(TimeRequest);
if(Signals & SIG_SERREAD)
{
WaitIO(ReadBuffer -> SerialRequest);
ReadBuffer -> IsBusy = FALSE;
ReadBuffer -> SerialFilled = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
ReadBuffer -> SerialIndex = ReadBuffer -> SerialBuffer;
ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
DoIO(ReadBuffer -> SerialRequest);
if(ReadBuffer -> SerialRequest -> IOSer . io_Actual)
{
LONG Size = ReadBuffer -> SerialSize - ReadBuffer -> SerialFilled;
if(Size > 0)
{
if(Size > ReadBuffer -> SerialRequest -> IOSer . io_Actual)
Size = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
ReadBuffer -> SerialRequest -> IOSer . io_Command = CMD_READ;
ReadBuffer -> SerialRequest -> IOSer . io_Data = ReadBuffer -> SerialBuffer + ReadBuffer -> SerialFilled;
ReadBuffer -> SerialRequest -> IOSer . io_Length = Size;
DoIO(ReadBuffer -> SerialRequest);
ReadBuffer -> SerialFilled += ReadBuffer -> SerialRequest -> IOSer . io_Actual;
}
}
}
if(Signals & SIG_SERWRITE)
{
struct SerialBuffer *Swap = ThisBuffer;
WaitIO(ThisBuffer -> SerialRequest);
ThisBuffer -> IsBusy = FALSE;
ThisBuffer -> SerialIndex = ThisBuffer -> SerialBuffer;
ThisBuffer = NextBuffer;
NextBuffer = Swap;
}
if(Signals & SIG_CONREAD)
{
WaitIO(ConsoleReadRequest);
ConsoleReady = TRUE;
}
if(Signals & SIG_WINDOW)
WindowReady = TRUE;
}
/* com_outfull(VOID):
*
* Return number of bytes still to be transferred.
*/
int
com_outfull(VOID)
{
return(ThisBuffer -> SerialIndex - ThisBuffer -> SerialBuffer + NextBuffer -> SerialIndex - NextBuffer -> SerialBuffer);
}
/* carrier(VOID):
*
* Return current carrier status.
*/
int
carrier(VOID)
{
if(nocarrier)
return(1);
else
{
if(!ThisBuffer -> IsBusy)
{
ThisBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
DoIO(ThisBuffer -> SerialRequest);
if(ThisBuffer -> SerialRequest -> io_Status & CIAF_COMCD)
return(0);
else
return(1);
}
else
{
NextBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
DoIO(NextBuffer -> SerialRequest);
if(NextBuffer -> SerialRequest -> io_Status & CIAF_COMCD)
return(0);
else
return(1);
}
}
}
/* com_flush(VOID):
*
* Make sure all pending data gets written.
*/
VOID
com_flush(VOID)
{
if(ThisBuffer -> IsBusy)
{
WaitIO(ThisBuffer -> SerialRequest);
ThisBuffer -> IsBusy = FALSE;
ThisBuffer -> SerialIndex = ThisBuffer -> SerialBuffer;
}
if(NextBuffer -> SerialIndex > NextBuffer -> SerialBuffer)
{
NextBuffer -> SerialRequest -> IOSer . io_Command = CMD_WRITE;
NextBuffer -> SerialRequest -> IOSer . io_Data = NextBuffer -> SerialBuffer;
NextBuffer -> SerialRequest -> IOSer . io_Length = NextBuffer -> SerialIndex - NextBuffer -> SerialBuffer;
DoIO(NextBuffer -> SerialRequest);
NextBuffer -> SerialIndex = NextBuffer -> SerialBuffer;
}
}
/* com_putbyte(byte c):
*
* Transmit a single byte, queueing it if necessary.
*/
VOID
com_putbyte(byte c)
{
if(ThisBuffer -> IsBusy)
{
if(NextBuffer -> SerialIndex + 1 >= NextBuffer -> SerialTop)
{
struct SerialBuffer *Swap = ThisBuffer;
WaitIO(ThisBuffer -> SerialRequest);
ThisBuffer -> IsBusy = FALSE;
ThisBuffer -> SerialIndex = ThisBuffer -> SerialBuffer;
ThisBuffer = NextBuffer;
NextBuffer = Swap;
ThisBuffer -> IsBusy = TRUE;
ThisBuffer -> SerialRequest -> IOSer . io_Command = CMD_WRITE;
ThisBuffer -> SerialRequest -> IOSer . io_Data = ThisBuffer -> SerialBuffer;
ThisBuffer -> SerialRequest -> IOSer . io_Length = ThisBuffer -> SerialIndex - ThisBuffer -> SerialBuffer;
ClrSignal(SIG_SERWRITE);
SendIO(ThisBuffer -> SerialRequest);
}
*NextBuffer -> SerialIndex++ = c;
}
else
{
if(ThisBuffer -> SerialIndex + 1 < ThisBuffer -> SerialTop)
{
*ThisBuffer -> SerialIndex++ = c;
ThisBuffer -> IsBusy = TRUE;
ThisBuffer -> SerialRequest -> IOSer . io_Command = CMD_WRITE;
ThisBuffer -> SerialRequest -> IOSer . io_Data = ThisBuffer -> SerialBuffer;
ThisBuffer -> SerialRequest -> IOSer . io_Length = 1;
ClrSignal(SIG_SERWRITE);
SendIO(ThisBuffer -> SerialRequest);
}
else
{
ThisBuffer -> IsBusy = TRUE;
ThisBuffer -> SerialRequest -> IOSer . io_Command = CMD_WRITE;
ThisBuffer -> SerialRequest -> IOSer . io_Data = ThisBuffer -> SerialBuffer;
ThisBuffer -> SerialRequest -> IOSer . io_Length = ThisBuffer -> SerialIndex - ThisBuffer -> SerialBuffer;
ClrSignal(SIG_SERWRITE);
SendIO(ThisBuffer -> SerialRequest);
*NextBuffer -> SerialIndex++ = c;
}
}
}
/* com_purge(VOID):
*
* Clear the read/write buffers.
*/
VOID
com_purge(VOID)
{
if(ThisBuffer -> IsBusy)
{
if(!CheckIO(ThisBuffer -> SerialRequest))
AbortIO(ThisBuffer -> SerialRequest);
WaitIO(ThisBuffer -> SerialRequest);
}
ThisBuffer -> IsBusy = FALSE;
ThisBuffer -> SerialIndex = ThisBuffer -> SerialBuffer;
NextBuffer -> IsBusy = FALSE;
NextBuffer -> SerialIndex = NextBuffer -> SerialBuffer;
if(ReadBuffer -> IsBusy)
{
if(!CheckIO(ReadBuffer -> SerialRequest))
AbortIO(ReadBuffer -> SerialRequest);
WaitIO(ReadBuffer -> SerialRequest);
}
ReadBuffer -> IsBusy = FALSE;
ReadBuffer -> SerialIndex = ReadBuffer -> SerialBuffer;
ReadBuffer -> SerialFilled = 0;
ThisBuffer -> SerialRequest -> IOSer . io_Command = CMD_CLEAR;
DoIO(ThisBuffer -> SerialRequest);
}
/* com_dump(VOID):
*
* Wait for asynchronous write request to terminate.
*/
VOID
com_dump(VOID)
{
com_flush();
}
/* com_getbyte(VOID):
*
* Read a single byte from the serial line. If not available,
* return EOF.
*/
int
com_getbyte(VOID)
{
int Result;
if(ReadBuffer -> SerialFilled <= 0)
{
if(ReadBuffer -> IsBusy)
{
if(!CheckIO(ReadBuffer -> SerialRequest))
return(EOF);
else
WaitIO(ReadBuffer -> SerialRequest);
ReadBuffer -> IsBusy = FALSE;
ReadBuffer -> SerialFilled = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
ReadBuffer -> SerialIndex = ReadBuffer -> SerialBuffer;
ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
DoIO(ReadBuffer -> SerialRequest);
if(ReadBuffer -> SerialRequest -> IOSer . io_Actual)
{
LONG Size = ReadBuffer -> SerialSize - ReadBuffer -> SerialFilled;
if(Size > 0)
{
if(Size > ReadBuffer -> SerialRequest -> IOSer . io_Actual)
Size = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
ReadBuffer -> SerialRequest -> IOSer . io_Command = CMD_READ;
ReadBuffer -> SerialRequest -> IOSer . io_Data = ReadBuffer -> SerialBuffer + ReadBuffer -> SerialFilled;
ReadBuffer -> SerialRequest -> IOSer . io_Length = Size;
DoIO(ReadBuffer -> SerialRequest);
ReadBuffer -> SerialFilled += ReadBuffer -> SerialRequest -> IOSer . io_Actual;
}
}
}
else
{
ReadBuffer -> SerialRequest -> IOSer . io_Command = SDCMD_QUERY;
DoIO(ReadBuffer -> SerialRequest);
if(!ReadBuffer -> SerialRequest -> IOSer . io_Actual)
return(EOF);
else
{
ReadBuffer -> SerialRequest -> IOSer . io_Command = CMD_READ;
ReadBuffer -> SerialRequest -> IOSer . io_Data = ReadBuffer -> SerialBuffer;
ReadBuffer -> SerialRequest -> IOSer . io_Length = MIN(ReadBuffer -> SerialRequest -> IOSer . io_Actual,ReadBuffer -> SerialSize);
DoIO(ReadBuffer -> SerialRequest);
if(!ReadBuffer -> SerialRequest -> IOSer . io_Actual)
return(EOF);
else
{
ReadBuffer -> SerialFilled = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
ReadBuffer -> SerialIndex = ReadBuffer -> SerialBuffer;
}
}
}
}
Result = *ReadBuffer -> SerialIndex++;
ReadBuffer -> SerialFilled--;
if(ReadBuffer -> SerialFilled <= 0)
{
ReadBuffer -> IsBusy = TRUE;
ReadBuffer -> SerialIndex = ReadBuffer -> SerialBuffer;
ReadBuffer -> SerialRequest -> IOSer . io_Command = CMD_READ;
ReadBuffer -> SerialRequest -> IOSer . io_Data = ReadBuffer -> SerialBuffer;
ReadBuffer -> SerialRequest -> IOSer . io_Length = 1;
ClrSignal(SIG_SERREAD);
SendIO(ReadBuffer -> SerialRequest);
}
return(Result);
}
/* setstamp(STRPTR Name,LONG Time):
*
* Set time/date of a file.
*/
VOID
setstamp(char *Name,long Time)
{
struct tm *t;
struct ClockData ClockData;
ULONG Seconds;
struct DateStamp Date;
t = localtime(&Time);
ClockData . sec = t -> tm_sec;
ClockData . min = t -> tm_min;
ClockData . hour = t -> tm_hour;
ClockData . mday = t -> tm_mday;
ClockData . month = t -> tm_mon;
ClockData . year = t -> tm_year + 1900;
Seconds = Date2Amiga(&ClockData);
Date . ds_Days = Seconds / (24 * 60 * 60);
Date . ds_Minute = (Seconds % (24 * 60 * 60)) / 60;
Date . ds_Tick = (Seconds % 60) * TICKS_PER_SECOND;
SetFileDate(Name,&Date);
}
/* freespace(STRPTR DrivePath):
*
* Get free disk space for specified drive.
*/
long
freespace(char *DrivePath)
{
struct DevProc *DevProc = GetDeviceProc(DrivePath,NULL);
struct DosList *DosList;
BOOL GoodDevice = FALSE;
LONG Size = (LONG)((ULONG)~0 >> 2);
if(DosList = LockDosList(LDF_DEVICES | LDF_READ))
{
while(DosList = NextDosEntry(DosList,LDF_DEVICES))
{
if(DosList -> dol_Task == DevProc -> dvp_Port)
{
struct FileSysStartupMsg *FSSM = (struct FileSysStartupMsg *)BADDR(DosList -> dol_misc . dol_handler . dol_Startup);
if(TypeOfMem(FSSM))
{
struct DosEnvec *DosEnvec = (struct DosEnvec *)BADDR(FSSM -> fssm_Environ);
STRPTR Name = (STRPTR)BADDR(FSSM -> fssm_Device);
if(TypeOfMem(DosEnvec) && TypeOfMem(Name))
{
if(Name[0] > 0 && !Name[(WORD)Name[0] + 1])
{
struct IOStdReq __aligned IORequest;
if(!OpenDevice(Name + 1,FSSM -> fssm_Unit,&IORequest,FSSM -> fssm_Unit))
{
CloseDevice(&IORequest);
if(DosEnvec -> de_TableSize > 0 && DosEnvec -> de_LowCyl <= DosEnvec -> de_HighCyl)
GoodDevice = TRUE;
}
}
}
}
}
}
UnLockDosList(LDF_DEVICES | LDF_READ);
}
FreeDeviceProc(DevProc);
if(GoodDevice)
{
struct InfoData *InfoData;
if(InfoData = (struct InfoData *)AllocVec(sizeof(struct InfoData),MEMF_ANY | MEMF_PUBLIC))
{
UBYTE NewName[256],*Index;
BPTR FileLock;
memcpy(NewName,DrivePath,255);
NewName[255] = 0;
Index = PathPart(NewName);
*Index = 0;
FileLock = Lock(NewName,ACCESS_READ);
if(FileLock)
{
if(Info(FileLock,InfoData))
Size = InfoData -> id_BytesPerBlock * (InfoData -> id_NumBlocks - InfoData -> id_NumBlocksUsed);
UnLock(FileLock);
}
FreeVec(InfoData);
}
}
return(Size);
}
/* ffirst(char *FileSpec):
*
* Return name of first file matching the given specs.
*/
char *
ffirst(char *filespec)
{
AnchorUsed = TRUE;
if(MatchFirst(filespec,Anchor))
return(NULL);
else
return((char *)Anchor -> ap_Buf);
}
/* fnext(VOID):
*
* Return name of next file matching the given specs.
*/
char *
fnext(VOID)
{
AnchorUsed = TRUE;
if(MatchNext(Anchor))
return(NULL);
else
return((char *)Anchor -> ap_Buf);
}