2 Copyright © 1995-2016, The AROS Development Team. All rights reserved.
9 /* HISTORY: 28.01.2001 SDuvan -- Implemented */
14 #include <aros/debug.h>
16 #include <aros/asmcall.h>
18 #include <proto/realtime.h>
19 #include <proto/utility.h>
20 #include <proto/exec.h>
21 #include <proto/alib.h>
22 #include <exec/lists.h>
23 #include <exec/tasks.h>
24 #include <libraries/realtime.h>
26 #include "realtime_intern.h"
28 /* This should perhaps run as a task with a very high priority (as we must
29 use semaphores) and which is signalled by the timer interrupt */
31 AROS_UFH3(void, Pulse
,
32 AROS_UFHA(STRPTR
, argPtr
, A0
),
33 AROS_UFHA(ULONG
, argSize
, D0
),
34 AROS_UFHA(struct ExecBase
*, sysBase
, A6
))
38 struct internal_RealTimeBase
*RealTimeBase
= GPB(FindTask(NULL
)->tc_UserData
);
40 struct Conductor
*conductor
;
41 struct Player
*player
;
42 struct pmTime timeMsg
;
46 D(bug("Pulse task entered (%p)\n", FindTask(NULL
));)
53 signals
= Wait(SIGF_SINGLE
| SIGBREAKF_CTRL_C
);
55 if (signals
& SIGBREAKF_CTRL_C
)
61 /* It was SIGF_SINGLE */
63 /* NOTE! 12 should be 1, but as the timing source is the VBlank
64 running at 50Hz instead of the real heartbeat running at
65 600 Hz, we scale things up
66 -The hartbeat is actually supposed to be 1200 Hz, so I
67 changed 12 up to 24. -ksvalast.
69 GPB(RealTimeBase
)->rtb_Time
+= 24; /* Not sure about that frac time... maybe
70 to take care of other sync sources
71 (not external) whose heartbeats
72 aliases against 600Hz? */
73 time
= GPB(RealTimeBase
)->rtb_Time
;
75 timeMsg
.pmt_Method
= PM_TICK
;
76 timeMsg
.pmt_Time
= time
;
78 lock
= LockRealTime(RT_CONDUCTORS
);
80 ForeachNode(&RealTimeBase
->rtb_ConductorList
, conductor
)
82 if (conductor
->cdt_State
== CONDSTATE_RUNNING
)
84 // kprintf("Found running conductor '%s'\n",
85 // conductor->cdt_Link.ln_Name);
87 if (conductor
->cdt_Flags
& CONDUCTF_EXTERNAL
)
89 if (!(conductor
->cdt_Flags
& CONDUCTF_GOTTICK
))
94 /* TODO: Fix wrap-around calculations */
96 /* This conductor has an external sync source */
97 if (time
< conductor
->cdt_ExternalTime
)
99 /* Align the time to the external source */
100 conductor
->cdt_ClockTime
= conductor
->cdt_ExternalTime
;
102 else if(time
> conductor
->cdt_MaxExternalTime
)
104 /* This time was not within the constraints, so we
105 cannot report it -- we have to wait for the
106 external synchronizer to call ExternalSync()
107 with new values. Note that the conducor's time
108 is not incremented in this case. */
114 /* This conductor doesn't have an external sync source.
115 Increment conductor time */
116 conductor
->cdt_ClockTime
+=24;
119 conductor
->cdt_Flags
&= ~CONDUCTF_METROSET
;
121 ForeachNode(&conductor
->cdt_Players
, player
)
123 // kprintf("Found player '%s' ready = %i, quiet = %i\n",
124 // player->pl_Link.ln_Name,
125 // player->pl_Flags & PLAYERF_READY ? 1 : 0,
126 // player->pl_Flags & PLAYERF_QUIET ? 1 : 0);
128 if (!(player
->pl_Flags
& PLAYERF_QUIET
) &&
129 player
->pl_Flags
& PLAYERF_READY
)
131 // kprintf("Found active player\n");
133 if (player
->pl_Hook
!= NULL
)
135 // kprintf("Calling hook %p\n", player->pl_Hook);
136 CallHookA(player
->pl_Hook
, player
, &timeMsg
);
140 player
->pl_MetricTime
= conductor
->cdt_ClockTime
;
144 if (player
->pl_Flags
& PLAYERF_ALARMSET
)
146 if (player
->pl_AlarmTime
<= player
->pl_MetricTime
)
149 if (player
->pl_Reserved0
!= -1)
151 Signal(player
->pl_Task
,
152 1 << player
->pl_Reserved0
);
157 } /* For each active player */
159 } /* For each conductor whose clock is running */
161 UnlockRealTime(lock
);