Do not install wrong cache routine if called before SysBase is complete.
[AROS.git] / workbench / libs / realtime / realtime_init.c
blobefb9b87c8be83e7f55496ba79e03b90e7dad3d58
1 /*
2 Copyright © 1995-2006, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Realtime.library initialization code.
6 Lang: English.
7 */
9 /* HISTORY: 25.06.99 SDuvan Began implementing... */
13 #include <utility/utility.h>
15 #include <exec/types.h>
16 #include <exec/resident.h>
17 #include <exec/interrupts.h>
18 #include <hardware/intbits.h>
19 #include <dos/dos.h>
20 #include <proto/dos.h>
21 #include <proto/exec.h>
22 #include <utility/tagitem.h>
23 #include <aros/symbolsets.h>
25 #include <exec/libraries.h>
27 #include "realtime_intern.h"
28 #include LC_LIBDEFS_FILE
30 #undef DEBUG
31 #define DEBUG 1
32 #include <aros/debug.h>
34 BOOL AllocTimer(struct internal_RealTimeBase *RealTimeBase);
35 void FreeTimer(struct internal_RealTimeBase *RealTimeBase);
37 extern void Pulse();
39 static int Init(LIBBASETYPEPTR LIBBASE)
41 /* This function is single-threaded by exec by calling Forbid. */
43 WORD i; /* Loop variable */
45 for(i = 0; i < RT_MAXLOCK; i++)
47 InitSemaphore(&RealTimeBase->rtb_Locks[i]);
50 NEWLIST(&RealTimeBase->rtb_ConductorList);
52 RealTimeBase->rtb_TickErr = 0; /* How may such a thing be measured? */
54 /* I use a process here just to be able to use CreateNewProc() so
55 I don't have to fiddle with stack order and such... */
57 struct TagItem tags[] = { { NP_Entry , (IPTR)Pulse },
58 { NP_Name , (IPTR)"RealTime Pulse" },
59 { NP_Priority, (IPTR)127 },
60 { NP_UserData, (IPTR)RealTimeBase },
61 { TAG_DONE , (IPTR)NULL } };
63 GPB(RealTimeBase)->rtb_PulseTask = (struct Task *)CreateNewProc(tags);
66 if (GPB(RealTimeBase)->rtb_PulseTask == NULL)
68 return FALSE;
71 kprintf("Realtime pulse task created\n");
73 if (!AllocTimer((struct internal_RealTimeBase *)RealTimeBase))
75 return FALSE;
78 kprintf("Realtime pulse timer created\n");
80 return TRUE;
84 static int Expunge(LIBBASETYPEPTR LIBBASE)
87 This function is single-threaded by exec by calling Forbid.
88 Never break the Forbid() or strange things might happen.
91 FreeTimer(RealTimeBase);
93 /* Shut down the pulse message task -- must be done AFTER freeing the
94 timer! */
95 Signal(RealTimeBase->rtb_PulseTask, SIGBREAKF_CTRL_C);
97 return TRUE;
101 /* RealTime timer interrupt -- currently only a VBlank interrupt */
102 AROS_UFH4(ULONG, rtVBlank,
103 AROS_UFHA(ULONG, dummy, A0),
104 AROS_UFHA(void *, data, A1),
105 AROS_UFHA(ULONG, dummy2, A5),
106 AROS_UFHA(struct ExecBase *, mySysBase, A6))
108 AROS_USERFUNC_INIT
109 struct internal_RealTimeBase *RealTimeBase = GPB(data);
111 // kprintf("Signalling task %p\n", RealTimeBase->rtb_PulseTask);
112 Signal(RealTimeBase->rtb_PulseTask, SIGF_SINGLE);
114 return 0;
116 AROS_USERFUNC_EXIT
120 BOOL AllocTimer(struct internal_RealTimeBase *RealTimeBase)
122 /* TODO */
123 /* This should be replaced by some timer.device thing when an accurate
124 timer is available -- UNIT_MICROHZ? */
126 RealTimeBase->rtb_VBlank.is_Code = (APTR)&rtVBlank;
127 RealTimeBase->rtb_VBlank.is_Data = (APTR)RealTimeBase;
128 RealTimeBase->rtb_VBlank.is_Node.ln_Name = "RealTime VBlank server";
129 RealTimeBase->rtb_VBlank.is_Node.ln_Pri = 127;
130 RealTimeBase->rtb_VBlank.is_Node.ln_Type = NT_INTERRUPT;
132 /* Add a VBLANK server to take care of the heartbeats. */
133 AddIntServer(INTB_VERTB, &RealTimeBase->rtb_VBlank);
135 return TRUE;
139 void FreeTimer(struct internal_RealTimeBase *RealTimeBase)
141 RemIntServer(INTB_VERTB, &RealTimeBase->rtb_VBlank);
145 ADD2INITLIB(Init, 0);
146 ADD2EXPUNGELIB(Expunge, 0);