2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
9 /* HISTORY: 28.01.2001 SDuvan -- Implemented */
12 #include <aros/debug.h>
13 #include <aros/asmcall.h>
15 #include <proto/realtime.h>
16 #include <proto/utility.h>
17 #include <proto/exec.h>
18 #include <proto/alib.h>
19 #include <exec/lists.h>
20 #include <exec/tasks.h>
21 #include <libraries/realtime.h>
23 #include "realtime_intern.h"
25 /* This should perhaps run as a task with a very high priority (as we must
26 use semaphores) and which is signalled by the timer interrupt */
28 AROS_UFH3(void, Pulse
,
29 AROS_UFHA(STRPTR
, argPtr
, A0
),
30 AROS_UFHA(ULONG
, argSize
, D0
),
31 AROS_UFHA(struct ExecBase
*, sysBase
, A6
))
35 struct internal_RealTimeBase
*RealTimeBase
= GPB(FindTask(NULL
)->tc_UserData
);
37 struct Conductor
*conductor
;
38 struct Player
*player
;
39 struct pmTime timeMsg
;
43 kprintf("Pulse task entered (%p)\n", FindTask(NULL
));
50 signals
= Wait(SIGF_SINGLE
| SIGBREAKF_CTRL_C
);
52 if (signals
& SIGBREAKF_CTRL_C
)
58 /* It was SIGF_SINGLE */
60 /* NOTE! 12 should be 1, but as the timing source is the VBlank
61 running at 50Hz instead of the real heartbeat running at
62 600 Hz, we scale things up
63 -The hartbeat is actually supposed to be 1200 Hz, so I
64 changed 12 up to 24. -ksvalast.
66 GPB(RealTimeBase
)->rtb_Time
+= 24; /* Not sure about that frac time... maybe
67 to take care of other sync sources
68 (not external) whose heartbeats
69 aliases against 600Hz? */
70 time
= GPB(RealTimeBase
)->rtb_Time
;
72 timeMsg
.pmt_Method
= PM_TICK
;
73 timeMsg
.pmt_Time
= time
;
75 lock
= LockRealTime(RT_CONDUCTORS
);
77 ForeachNode(&GPB(RealTimeBase
)->rtb_ConductorList
, conductor
)
79 if (conductor
->cdt_State
== CONDSTATE_RUNNING
)
81 // kprintf("Found running conductor '%s'\n",
82 // conductor->cdt_Link.ln_Name);
84 if (conductor
->cdt_Flags
& CONDUCTF_EXTERNAL
)
86 if (!conductor
->cdt_Flags
& CONDUCTF_GOTTICK
)
91 /* TODO: Fix wrap-around calculations */
93 /* This conductor has an external sync source */
94 if (time
< conductor
->cdt_ExternalTime
)
96 /* Align the time to the external source */
97 conductor
->cdt_ClockTime
= conductor
->cdt_ExternalTime
;
99 else if(time
> conductor
->cdt_MaxExternalTime
)
101 /* This time was not within the constraints, so we
102 cannot report it -- we have to wait for the
103 external synchronizer to call ExternalSync()
104 with new values. Note that the conducor's time
105 is not incremented in this case. */
111 /* This conductor doesn't have an external sync source.
112 Increment conductor time */
113 conductor
->cdt_ClockTime
+=24;
116 conductor
->cdt_Flags
&= ~CONDUCTF_METROSET
;
118 ForeachNode(&conductor
->cdt_Players
, player
)
120 // kprintf("Found player '%s' ready = %i, quiet = %i\n",
121 // player->pl_Link.ln_Name,
122 // player->pl_Flags & PLAYERF_READY ? 1 : 0,
123 // player->pl_Flags & PLAYERF_QUIET ? 1 : 0);
125 if (!(player
->pl_Flags
& PLAYERF_QUIET
) &&
126 player
->pl_Flags
& PLAYERF_READY
)
128 // kprintf("Found active player\n");
130 if (player
->pl_Hook
!= NULL
)
132 // kprintf("Calling hook %p\n", player->pl_Hook);
133 CallHookA(player
->pl_Hook
, &timeMsg
, player
);
137 player
->pl_MetricTime
= conductor
->cdt_ClockTime
;
141 if (player
->pl_Flags
& PLAYERF_ALARMSET
)
143 if (player
->pl_AlarmTime
<= player
->pl_MetricTime
)
146 if (player
->pl_Reserved0
!= -1)
148 Signal(player
->pl_Task
,
149 1 << player
->pl_Reserved0
);
154 } /* For each active player */
156 } /* For each conductor whose clock is running */
158 UnlockRealTime(lock
);