home *** CD-ROM | disk | FTP | other *** search
- /*
- * UnixClock - make the amiga hardware clock behave like a UNIX clock
- *
- * © Copyright 1995 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
- * © Copyright 1997 by Gunther Nikl (gnikl@informatik.uni-rostock.de)
- *
- * -----------------------------------------------------------------------------
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.
- */
-
- /*
- ** includes
- */
-
- #include <exec/types.h>
-
- #ifndef REG
- #define REG(x) asm(#x)
- #endif
-
- #include <dos/dos.h>
- #include <dos/dosextens.h>
- #include <devices/timer.h>
- #include <libraries/locale.h>
- #include <resources/battclock.h>
- #include <proto/battclock.h>
- #include <proto/locale.h>
- #include <proto/exec.h>
-
- /*
- ** nifty structure
- */
-
- struct BattInfo {
- ULONG (*OldReadBattClock)();
- VOID (*OldWriteBattClock)(ULONG REG(d0));
- ULONG GMTOffset;
- } bi;
-
- /*
- ** skip any const data and functions *in front of* our Main !
- */
-
- REG(jra _Main);
-
- /*
- ** patches
- */
-
- ULONG NewReadBattClock()
- {
- return (*bi.OldReadBattClock)()-bi.GMTOffset;
- }
-
- VOID NewWriteBattClock(ULONG time REG(d0))
- {
- (*bi.OldWriteBattClock)(time+bi.GMTOffset);
- }
-
- /*
- ** support
- */
-
- STATIC VOID SetClock(struct ExecBase *SysBase REG(a6), struct timerequest *tr REG(a1), ULONG time REG(d0))
- {
- tr->tr_node.io_Command = TR_SETSYSTIME;
- tr->tr_node.io_Flags = IOF_QUICK;
- tr->tr_time.tv_micro = 0;
- tr->tr_time.tv_secs = time;
- DoIO(&tr->tr_node);
- }
-
- /*
- ** version
- */
-
- const char version[] = "$VER: UnixClock 1.1 (13.2.97)";
-
- /*
- ** main
- */
-
- #define PORTNAME "UC.rendezvous"
-
- LONG Main()
- {
- struct LocaleBase *LocaleBase;
- struct Node *BattClockBase;
- struct ExecBase *SysBase;
- struct timerequest *treq;
- struct MsgPort *tport,*mp;
- struct Message *wbmsg;
- struct Process *pr;
-
- SysBase = *(struct ExecBase **)4L; pr = (struct Process *)FindTask(NULL);
-
- wbmsg = NULL;
-
- if (!pr->pr_CLI) {
- WaitPort(&pr->pr_MsgPort); wbmsg = GetMsg(&pr->pr_MsgPort);
- }
-
- Forbid();
- if ((mp=FindPort(PORTNAME)) == NULL)
- if ((tport=CreateMsgPort()) != NULL) {
- tport->mp_Node.ln_Name = PORTNAME; AddPort(tport);
- }
- Permit();
-
- if (!mp && tport) {
- if ((BattClockBase=OpenResource(BATTCLOCKNAME)) != NULL) {
- if ((LocaleBase=(struct LocaleBase *)OpenLibrary("locale.library",38L)) != NULL) {
- bi.GMTOffset = 60 * (OpenLocale(NULL))->loc_GMTOffset;
- CloseLibrary((struct Library *)LocaleBase);
- if ((treq=CreateIORequest(tport, sizeof(*treq))) != NULL) {
- if (!OpenDevice(TIMERNAME, UNIT_VBLANK, &treq->tr_node, NULL)) {
- Forbid();
- bi.OldReadBattClock = SetFunction((struct Library *)BattClockBase, -12L, (APTR)NewReadBattClock);
- bi.OldWriteBattClock = SetFunction((struct Library *)BattClockBase, -18L, (APTR)NewWriteBattClock);
- Permit();
- SetClock(SysBase,treq,ReadBattClock());
- SetSignal(NULL, SIGBREAKF_CTRL_C); Wait(SIGBREAKF_CTRL_C);
- Forbid();
- (VOID)SetFunction((struct Library *)BattClockBase, -18L, (APTR)bi.OldWriteBattClock);
- (VOID)SetFunction((struct Library *)BattClockBase, -12L, (APTR)bi.OldReadBattClock);
- Permit();
- SetClock(SysBase,treq,ReadBattClock());
- CloseDevice(&treq->tr_node);
- }
- DeleteIORequest(treq);
- }
- }
- }
- RemPort(tport); DeleteMsgPort(tport);
- }
-
- if (wbmsg != NULL) {
- Forbid(); ReplyMsg(wbmsg);
- }
-
- return 0;
- }
-