home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / util / time / UnixClock.lha / UnixClock / UnixClock.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-13  |  3.4 KB  |  145 lines

  1. /*
  2.  *    UnixClock - make the amiga hardware clock behave like a UNIX clock
  3.  *
  4.  *    © Copyright 1995 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
  5.  *    © Copyright 1997 by Gunther Nikl (gnikl@informatik.uni-rostock.de)
  6.  *
  7.  *    -----------------------------------------------------------------------------
  8.  *
  9.  *    This file is subject to the terms and conditions of the GNU General Public
  10.  *    License.
  11.  */
  12.  
  13. /*
  14. ** includes
  15. */
  16.  
  17. #include <exec/types.h>
  18.  
  19. #ifndef REG
  20. #define REG(x) asm(#x)
  21. #endif
  22.  
  23. #include <dos/dos.h>
  24. #include <dos/dosextens.h>
  25. #include <devices/timer.h>
  26. #include <libraries/locale.h>
  27. #include <resources/battclock.h>
  28. #include <proto/battclock.h>
  29. #include <proto/locale.h>
  30. #include <proto/exec.h>
  31.  
  32. /*
  33. ** nifty structure
  34. */
  35.  
  36. struct BattInfo {
  37.   ULONG (*OldReadBattClock)();
  38.   VOID  (*OldWriteBattClock)(ULONG REG(d0));
  39.   ULONG GMTOffset;
  40. } bi;
  41.  
  42. /*
  43. ** skip any const data and functions *in front of* our Main !
  44. */
  45.  
  46. REG(jra _Main);
  47.  
  48. /*
  49. ** patches
  50. */
  51.  
  52. ULONG NewReadBattClock()
  53. {
  54.   return (*bi.OldReadBattClock)()-bi.GMTOffset;
  55. }
  56.  
  57. VOID NewWriteBattClock(ULONG time REG(d0))
  58. {
  59.   (*bi.OldWriteBattClock)(time+bi.GMTOffset);
  60. }
  61.  
  62. /*
  63. ** support
  64. */
  65.  
  66. STATIC VOID SetClock(struct ExecBase *SysBase REG(a6), struct timerequest *tr REG(a1), ULONG time REG(d0))
  67. {
  68.   tr->tr_node.io_Command = TR_SETSYSTIME;
  69.   tr->tr_node.io_Flags   = IOF_QUICK;
  70.   tr->tr_time.tv_micro   = 0;
  71.   tr->tr_time.tv_secs    = time;
  72.   DoIO(&tr->tr_node);
  73. }
  74.  
  75. /*
  76. ** version
  77. */
  78.  
  79. const char version[] = "$VER: UnixClock 1.1 (13.2.97)";
  80.  
  81. /*
  82. ** main
  83. */
  84.  
  85. #define PORTNAME "UC.rendezvous"
  86.  
  87. LONG Main()
  88. {
  89.   struct LocaleBase *LocaleBase;
  90.   struct Node *BattClockBase;
  91.   struct ExecBase *SysBase;
  92.   struct timerequest *treq;
  93.   struct MsgPort *tport,*mp;
  94.   struct Message *wbmsg;
  95.   struct Process *pr;
  96.  
  97.   SysBase = *(struct ExecBase **)4L; pr = (struct Process *)FindTask(NULL);
  98.  
  99.   wbmsg = NULL;
  100.  
  101.   if (!pr->pr_CLI) {
  102.     WaitPort(&pr->pr_MsgPort); wbmsg = GetMsg(&pr->pr_MsgPort);
  103.   }
  104.  
  105.   Forbid();
  106.   if ((mp=FindPort(PORTNAME)) == NULL)
  107.     if ((tport=CreateMsgPort()) != NULL) {
  108.       tport->mp_Node.ln_Name = PORTNAME; AddPort(tport);
  109.     }
  110.   Permit();
  111.  
  112.   if (!mp && tport) {
  113.     if ((BattClockBase=OpenResource(BATTCLOCKNAME)) != NULL) {
  114.       if ((LocaleBase=(struct LocaleBase *)OpenLibrary("locale.library",38L)) != NULL) {
  115.         bi.GMTOffset = 60 * (OpenLocale(NULL))->loc_GMTOffset;
  116.         CloseLibrary((struct Library *)LocaleBase);
  117.         if ((treq=CreateIORequest(tport, sizeof(*treq))) != NULL) {
  118.           if (!OpenDevice(TIMERNAME, UNIT_VBLANK, &treq->tr_node, NULL)) {
  119.             Forbid();
  120.             bi.OldReadBattClock  = SetFunction((struct Library *)BattClockBase, -12L, (APTR)NewReadBattClock);
  121.             bi.OldWriteBattClock = SetFunction((struct Library *)BattClockBase, -18L, (APTR)NewWriteBattClock);
  122.             Permit();
  123.             SetClock(SysBase,treq,ReadBattClock());
  124.             SetSignal(NULL, SIGBREAKF_CTRL_C); Wait(SIGBREAKF_CTRL_C);
  125.             Forbid();
  126.             (VOID)SetFunction((struct Library *)BattClockBase, -18L, (APTR)bi.OldWriteBattClock);
  127.             (VOID)SetFunction((struct Library *)BattClockBase, -12L, (APTR)bi.OldReadBattClock);
  128.             Permit();
  129.             SetClock(SysBase,treq,ReadBattClock());
  130.             CloseDevice(&treq->tr_node);
  131.           }
  132.           DeleteIORequest(treq);
  133.         }
  134.       }
  135.     }
  136.     RemPort(tport); DeleteMsgPort(tport);
  137.   }
  138.  
  139.   if (wbmsg != NULL) {
  140.     Forbid(); ReplyMsg(wbmsg);
  141.   }
  142.     
  143.   return 0;
  144. }
  145.