home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
back2roots/padua
/
padua.7z
/
padua
/
ftp.vapor.com
/
microdot-1
/
md1_src_02.lzx
/
amiga.c
< prev
next >
Wrap
C/C++ Source or Header
|
2014-05-19
|
21KB
|
933 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. */
#define ReadPort (ior.IOSer.io_Message.mn_ReplyPort)
#define WritePort (iow.IOSer.io_Message.mn_ReplyPort)
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/gadtools.h>
#include <proto/dos.h>
#include <proto/utility.h>
#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 "hydracom.h"
/* Serial buffer size. */
#define BUFFER_SIZE 8192
#define cprint(s) /**/
/* 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_TIMER (1UL << TimePort -> mp_SigBit)
/* A serial buffer structure. */
struct SerialBuffer
{
struct IOExtSer *SerialRequest;
UBYTE *SerialBuffer,
*SerialIndex,
*SerialTop;
LONG SerialSize,
SerialFilled;
BOOL IsClone,
IsBusy;
};
/* Library bases. */
struct Library *TimerBase;
/* Timer data. */
struct MsgPort *TimePort;
struct timerequest *TimeRequest;
/* Serial data. */
struct SerialBuffer *ThisBuffer,
*NextBuffer,
*ReadBuffer;
/* CloneSerialBuffer():
*
* Clone a SerialBuffer structure.
*/
extern struct IOExtSer ior, iow;
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(LONG Size)
{
struct SerialBuffer *Buffer;
//message( 0, " ioflags %lx", ior->io_SerFlags );
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;
Buffer -> SerialRequest = &ior;
return( Buffer );
}
else
cprint("Could not create serial buffer\n");
return(NULL);
}
/* OpenAll():
*
* Allocate all the resources required.
*/
STATIC BOOL
OpenAll( void )
{
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(!(ReadBuffer = CreateSerialBuffer(BUFFER_SIZE)))
return(FALSE);
if(!(ThisBuffer = CloneSerialBuffer(ReadBuffer,WritePort)))
return(FALSE);
if(!(NextBuffer = CloneSerialBuffer(ReadBuffer,WritePort)))
return(FALSE);
return(TRUE);
}
/* CloseAll():
*
* Close all the resources.
*/
STATIC VOID
CloseAll(VOID)
{
DeleteSerialBuffer(NextBuffer);
DeleteSerialBuffer(ThisBuffer);
DeleteSerialBuffer(ReadBuffer);
if(TimeRequest)
{
if(TimeRequest -> tr_node . io_Device)
CloseDevice(TimeRequest);
DeleteIORequest(TimeRequest);
}
if(TimePort)
DeleteMsgPort(TimePort);
}
/* 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);
}*/
VOID
com_putblock(byte *s,word len)
{
struct SerialBuffer *Swap = ThisBuffer;
//message( 0, " Entering computblock: len %ld", len );
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;
//message( 0, " cpb: before flush (1doio)" );
DoIO(ThisBuffer -> SerialRequest);
}
}
//message( 0, " computblock: before bufferswap" );
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;
//message( 0, " cpb: before flush (2doio)" );
DoIO(ThisBuffer -> SerialRequest);
}
ThisBuffer -> IsBusy = FALSE;
ThisBuffer -> SerialIndex = ThisBuffer -> SerialBuffer;
while(len > ( ( 2 * ThisBuffer -> SerialSize ) - 1 ) )
{
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;
//message( 0, " cpb: writeloop len = %ld", len );
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);
//message( 0, " cpb: qb1 len = %ld sx = %ld", len, ThisBuffer -> SerialRequest -> IOSer . io_Length );
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;
}
//message( 0, " exit computblock", 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())
{
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.
*/
extern struct Window *twindow;
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);
//message( 0, " Before Wait() in sys_idle t %lx, r %lx, w %lx", SIG_TIMER, SIG_SERREAD, SIG_SERWRITE );
Signals = Wait(SIG_SERREAD | SIG_SERWRITE | SIG_TIMER | (1L<<twindow->UserPort->mp_SigBit ));
//message( 0, " After Wait() in sys_idle %lx", Signals );
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;
}
//message( 0, " sys_idle: rbsf %ld", ReadBuffer->SerialFilled );
}
/* 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)
{
//message( 0, " XX com_putbyte; isbusy %ld, thisbuffer %lx", ThisBuffer->IsBusy, ThisBuffer );
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;
// BUG: LΣnge Falsch berechnet
// ThisBuffer -> SerialRequest -> IOSer . io_Length = 1;
ThisBuffer -> SerialRequest -> IOSer . io_Length = ThisBuffer -> SerialIndex - ThisBuffer -> SerialBuffer;
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))
{
//message( 0, " CGB: returning EOF" );
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)
{
//message( 0, " CGB: isbusy = FALSE, query = 0, EOF" );
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)
{
//message( 0, " CGB: EOF after valid query!!" );
return(EOF);
}
else
{
ReadBuffer -> SerialFilled = ReadBuffer -> SerialRequest -> IOSer . io_Actual;
ReadBuffer -> SerialIndex = ReadBuffer -> SerialBuffer;
}
}
}
}
/* if( !ReadBuffer->SerialFilled )
message( 0, " CGB: ERROR unexpected serialfilled = " );
if( ReadBuffer->IsBusy )
message( 0, " CGB: ERROR readbuffer->isbusy " );*/
Result = *ReadBuffer -> SerialIndex++;
ReadBuffer -> SerialFilled--;
if(ReadBuffer -> SerialFilled <= 0)
{
//message( 0, " CGB: queueing new rr" );
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);
}