home *** CD-ROM | disk | FTP | other *** search
- /*
- (C) 1995-96 AROS - The Amiga Replacement OS
- $Id$
-
- Desc: Timer.device
- Lang: english
- */
- #define timeval linux_timeval
- #include <sys/time.h>
- #undef timeval
- #include <devices/timer.h>
- #include <clib/exec_protos.h>
- #include <aros/libcall.h>
- #ifdef __GNUC__
- # include "nil_handler_gcc.h"
- #endif
-
- static const char name[];
- static const char version[];
- static const APTR inittabl[4];
- static void *const functable[];
- struct nilbase *AROS_SLIB_ENTRY(init,timer)();
- void AROS_SLIB_ENTRY(open,timer)();
- BPTR AROS_SLIB_ENTRY(close,timer)();
- BPTR AROS_SLIB_ENTRY(expunge,timer)();
- int AROS_SLIB_ENTRY(null,timer)();
- void AROS_SLIB_ENTRY(beginio,timer)();
- LONG AROS_SLIB_ENTRY(abortio,timer)();
- static const char end;
- static void NextTick (ULONG usec);
- static void timer (int dummy);
-
- int timer_entry(void)
- {
- /* If the handler was executed by accident return error code. */
- return -1;
- }
-
- const struct Resident timer_resident=
- {
- RTC_MATCHWORD,
- (struct Resident *)&timer_resident,
- (APTR)&end,
- RTF_AUTOINIT,
- 1,
- NT_DEVICE,
- 0,
- (char *)name,
- (char *)&version[6],
- (ULONG *)inittabl
- };
-
- static const char name[]=TIMERNAME;
-
- static const char version[]="$VER: " TIMERNAME " 1.0 (17.10.96)\n\015";
-
- static const APTR inittabl[4]=
- {
- (APTR)sizeof(struct timerbase),
- (APTR)functable,
- NULL,
- &AROS_SLIB_ENTRY(init,timer)
- };
-
- static void *const functable[]=
- {
- &AROS_SLIB_ENTRY(open,timer),
- &AROS_SLIB_ENTRY(close,timer),
- &AROS_SLIB_ENTRY(expunge,timer),
- &AROS_SLIB_ENTRY(null,timer),
- &AROS_SLIB_ENTRY(beginio,timer),
- &AROS_SLIB_ENTRY(abortio,timer),
- (void *)-1
- };
-
- AROS_LH2(struct timerbase *, init,
- AROS_LHA(struct timerbase *, timerbase, D0),
- AROS_LHA(BPTR, segList, A0),
- struct ExecBase *, sysBase, 0, timer)
- {
- AROS_LIBFUNC_INIT
- struct itimerval interval;
-
- /* Store arguments */
- timerbase->sysbase=sysBase;
- timerbase->seglist=segList;
-
- /* Start timer */
- signal (SIGALRM, timer);
-
- interval.it_interval.tv_sec = interval.it_value.tv_sec = 0;
- interval.it_interval.tv_usec = interval.it_value.tv_usec = 1000000/50;
-
- setitimer (ITIMER_REAL, &interval, NULL);
-
- return NULL;
- AROS_LIBFUNC_EXIT
- }
-
- AROS_LH3(void, open,
- AROS_LHA(struct IOFileSys *, iofs, A1),
- AROS_LHA(ULONG, unitnum, D0),
- AROS_LHA(ULONG, flags, D0),
- struct timerbase *, timerbase, 1, timer)
- {
- AROS_LIBFUNC_INIT
- struct TimeRequest *unit;
-
- /* Get compiler happy */
- unitnum=flags=0;
-
- /* I have one more opener. */
- timerbase->device.dd_Library.lib_OpenCnt++;
-
- /* Mark Message as recently used. */
- iofs->IOFS.io_Message.mn_Node.ln_Type=NT_REPLYMSG;
-
- unit=AllocMem(sizeof(struct TimeRequest),MEMF_PUBLIC|MEMF_CLEAR);
- if(dev!=NULL)
- {
- iofs->IOFS.io_Unit=(struct Unit *)unit;
- iofs->IOFS.io_Device=&timerbase->device;
- timerbase->device.dd_Library.lib_Flags&=~LIBF_DELEXP;
- iofs->IOFS.io_Error=0;
- return;
- }else
- iofs->io_DosError=ERROR_NO_FREE_STORE;
-
- iofs->IOFS.io_Error=IOERR_OPENFAIL;
- timerbase->device.dd_Library.lib_OpenCnt--;
-
- AROS_LIBFUNC_EXIT
- }
-
- AROS_LH1(BPTR, close,
- AROS_LHA(struct IOFileSys *, iofs, A1),
- struct timerbase *, timerbase, 2, timer)
- {
- AROS_LIBFUNC_INIT
- struct TimeRequest *unit;
-
- unit=(struct TimeRequest *)iofs->IOFS.io_Unit;
- if(unit->count)
- {
- iofs->io_DosError=ERROR_OBJECT_IN_USE;
- return 0;
- }
-
- /* Let any following attemps to use the device crash hard. */
- iofs->IOFS.io_Device=(struct Device *)-1;
- FreeMem(unit,sizeof(struct TimeRequest));
- iofs->io_DosError=0;
-
- /* I have one fewer opener. */
- timerbase->device.dd_Library.lib_OpenCnt --;
-
- return 0;
- AROS_LIBFUNC_EXIT
- }
-
- AROS_LH0(BPTR, expunge, struct timerbase *, timerbase, 3, timer)
- {
- AROS_LIBFUNC_INIT
- return 0; /* Never allow to expunge */
- AROS_LIBFUNC_EXIT
- }
-
- AROS_LH0I(int, null, struct timerbase *, timerbase, 4, timer)
- {
- AROS_LIBFUNC_INIT
- return 0;
- AROS_LIBFUNC_EXIT
- }
-
- AROS_LH1(void, beginio,
- AROS_LHA(struct timerequest *, tr, A1),
- struct timerbase *, timerbase, 5, timer)
- {
- AROS_LIBFUNC_INIT
- LONG error=0;
-
- /*
- Do everything quick no matter what. This is possible
- because I never need to Wait().
- */
- switch(tr->tr_node.io_Command)
- {
- case TR_ADDREQUEST:
-
- default:
- error=ERROR_NOT_IMPLEMENTED;
- break;
- }
-
- /* Set error code */
- tr->tr_node.io_Error=error;
-
- /* If the quick bit is not set send the message to the port */
- if(!(tr->tr_node.io_Flags&IOF_QUICK))
- ReplyMsg(&tr->tr_node.io_Message);
-
- AROS_LIBFUNC_EXIT
- }
-
- AROS_LH1(LONG, abortio,
- AROS_LHA(struct IOFileSys *, iofs, A1),
- struct timerbase *, timerbase, 6, timer)
- {
- AROS_LIBFUNC_INIT
- /* Everything already done. */
- return 0;
- AROS_LIBFUNC_EXIT
- }
-
- static void timer (int dummy)
- {
- signal (SIGALRM, timer);
-
- if (SysBase->TDNestCnt >= 0
- && SysBase->ThisTask->tc_Node.ln_Pri <=
- ((struct Task *)SysBase->TaskReady.lh_Head)->tc_Node.ln_Pri)
- Switch ();
- else
- SysBase->AttnResched |= 0x80;
- }
-
- static const char end=0;
-