comparison src/gpf2/osl/os_tim_ir.c @ 487:91e8dac34ada

src/gpf2/osl: initial import from old freecalypso-sw tree
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 22 Jun 2018 05:56:16 +0000
parents
children b4dd8c7e84ce
comparison
equal deleted inserted replaced
486:c433cca731a3 487:91e8dac34ada
1 /*
2 * This C module is a reconstruction based on the disassembly of
3 * os_tim.obj in frame_na7_db_ir.lib from the Leonardo package,
4 * subsequently reworked by Space Falcon.
5 *
6 * The original decompilation has been contributed by Das Signal.
7 */
8
9 /* set of included headers from COFF symtab: */
10 #include <stdio.h>
11 #include "gpfconf.h" /* FreeCalypso addition */
12 #include "../../nucleus/nucleus.h"
13 #include "typedefs.h"
14 #include "os.h"
15 #include "gdi.h"
16 #include "os_types.h"
17 #include "os_glob.h"
18
19 extern T_OS_TIMER_ENTRY TimerTable[];
20 extern T_OS_TIMER_TABLE_ENTRY *p_list[];
21
22 extern unsigned os_time_to_tick_multiplier;
23 extern unsigned os_tick_to_time_multiplier;
24
25 extern unsigned volatile t_start_ticks;
26 extern T_OS_TIMER_TABLE_ENTRY *t_running;
27 extern int used_timers;
28 extern int next_t_handle;
29 extern int volatile t_list_access;
30 extern int max_used_timers;
31 extern NU_SEMAPHORE TimSemCB;
32 extern NU_TIMER os_timer_cb;
33
34 #define BARRIER asm volatile ("": : :"memory")
35
36 void
37 timer_error(int err)
38 {
39 }
40
41 /* forward declaration */
42 void os_Timeout(UNSIGNED t_handle);
43
44 static int
45 os_remove_timer_from_list(T_OS_TIMER_TABLE_ENTRY *timer)
46 {
47 OS_TICK c_ticks;
48
49 if (timer != t_running) {
50 if (timer->next != t_running)
51 timer->next->r_ticks += timer->r_ticks;
52 } else {
53 c_ticks = NU_Retrieve_Clock();
54 if (timer->next == timer) {
55 t_running = 0;
56 } else {
57 timer->next->r_ticks =
58 t_start_ticks + timer->r_ticks +
59 timer->next->r_ticks - c_ticks;
60 t_running = timer->next;
61 }
62 NU_Control_Timer(&os_timer_cb, NU_DISABLE_TIMER);
63 if (t_running != NULL) {
64 t_start_ticks = c_ticks;
65 if (t_running->r_ticks != 0)
66 NU_Reset_Timer(&os_timer_cb, os_Timeout,
67 t_running->r_ticks, 0,
68 NU_ENABLE_TIMER);
69 }
70 }
71 if (timer->next != timer) {
72 timer->prev->next = timer->next;
73 timer->next->prev = timer->prev;
74 }
75 timer->next = NULL;
76 timer->prev = NULL;
77 timer->status = TMR_USED;
78 return TMR_USED;
79 }
80
81 static unsigned
82 os_add_timer_to_list(T_OS_TIMER_TABLE_ENTRY *timer, OS_TICK ticks)
83 {
84 T_OS_TIMER_TABLE_ENTRY *t_list;
85 OS_TICK c_ticks, e_ticks, r1_ticks, return_ticks;
86
87 if (ticks == 0)
88 ticks = 1;
89
90 c_ticks = NU_Retrieve_Clock();
91 t_list = t_running;
92 if (t_list != NULL) {
93 e_ticks = c_ticks - t_start_ticks;
94 if (t_list->r_ticks >= e_ticks) {
95 r1_ticks = t_list->r_ticks - e_ticks;
96 t_list->r_ticks = r1_ticks;
97 } else {
98 r1_ticks = 0;
99 t_list->r_ticks = 0;
100 }
101 t_start_ticks = c_ticks;
102 return_ticks = 0;
103 while (ticks >= r1_ticks) {
104 ticks -= r1_ticks;
105 t_list = t_list->next;
106 if (t_list == t_running)
107 goto out;
108 r1_ticks = t_list->r_ticks;
109 }
110 t_list->r_ticks -= ticks;
111 if (t_list == t_running) {
112 t_running = timer;
113 t_start_ticks = c_ticks;
114 NU_Control_Timer(&os_timer_cb, NU_DISABLE_TIMER);
115 return_ticks = ticks;
116 }
117 out:
118 timer->next = t_list;
119 timer->prev = t_list->prev;
120 t_list->prev->next = timer;
121 t_list->prev = timer;
122 timer->r_ticks = ticks;
123 } else {
124 timer->next = timer;
125 timer->prev = timer;
126 timer->r_ticks = ticks;
127 t_start_ticks = c_ticks;
128 t_running = timer;
129 return_ticks = ticks;
130 }
131 timer->status = TMR_ACTIVE;
132 return return_ticks;
133 }
134
135 void
136 os_Timeout(UNSIGNED t_handle) /* argument is unused */
137 {
138 ULONG s_ticks;
139 OS_HANDLE task_handle, e_handle;
140 USHORT t_index;
141 int i, done;
142 T_OS_TIMER_TABLE_ENTRY **t_r4;
143 T_OS_TIMER_TABLE_ENTRY *timer;
144 void (*timeout_func) (OS_HANDLE, OS_HANDLE, USHORT);
145
146 if (t_list_access) {
147 t_start_ticks++;
148 NU_Reset_Timer(&os_timer_cb, os_Timeout, 1, 0,
149 NU_ENABLE_TIMER);
150 return;
151 }
152
153 timer = t_running;
154 if (timer) {
155 s_ticks = 0;
156 done = 0;
157 i = 0;
158 do {
159 timeout_func = timer->TimeoutProc;
160 if (timer->p_ticks)
161 p_list[i++] = timer;
162 task_handle = timer->task_handle;
163 e_handle = timer->entity_handle;
164 t_index = timer->t_index;
165 timer->status = TMR_USED;
166 if (timer->next == timer) {
167 t_running = NULL;
168 done = 1;
169 } else {
170 timer->prev->next = timer->next;
171 timer->next->prev = timer->prev;
172 if (timer->next->r_ticks) {
173 t_running = timer->next;
174 s_ticks = timer->next->r_ticks;
175 done = 1;
176 } else
177 timer = timer->next;
178 }
179 timeout_func(task_handle, e_handle, t_index);
180 }
181 while (!done);
182
183 if (s_ticks) {
184 t_start_ticks = NU_Retrieve_Clock();
185 NU_Reset_Timer(&os_timer_cb, os_Timeout, s_ticks, 0,
186 NU_ENABLE_TIMER);
187 }
188 }
189 for (t_r4 = p_list; *t_r4; t_r4++) {
190 timer = *t_r4;
191 s_ticks = os_add_timer_to_list(timer, timer->p_ticks);
192 if (s_ticks)
193 NU_Reset_Timer(&os_timer_cb, os_Timeout, s_ticks, 0,
194 NU_ENABLE_TIMER);
195 *t_r4 = NULL;
196 }
197 }
198
199 GLOBAL LONG os_StartTimer(OS_HANDLE TaskHandle, OS_HANDLE TimerHandle,
200 USHORT Index, OS_TIME InitialTime,
201 OS_TIME RescheduleTime)
202 {
203 T_OS_TIMER_TABLE_ENTRY *timer;
204 OS_TICK ticks;
205 STATUS sts;
206
207 if (TimerHandle > MaxSimultaneousTimer)
208 return(OS_ERROR);
209 timer = &TimerTable[TimerHandle].entry;
210 sts = NU_Obtain_Semaphore(&TimSemCB, NU_SUSPEND);
211 if (timer->status == TMR_FREE) {
212 if (sts == NU_SUCCESS)
213 NU_Release_Semaphore(&TimSemCB);
214 return(OS_ERROR);
215 }
216 t_list_access = 1;
217 BARRIER;
218 if (timer->status == TMR_ACTIVE)
219 os_remove_timer_from_list(timer);
220 timer->t_handle = TimerHandle;
221 timer->task_handle = os_MyHandle();
222 timer->entity_handle = TaskHandle;
223 timer->t_index = Index;
224 timer->p_ticks = TIME_TO_SYSTEM_TICKS(RescheduleTime);
225 ticks = os_add_timer_to_list(timer, TIME_TO_SYSTEM_TICKS(InitialTime));
226 if (ticks)
227 NU_Reset_Timer(&os_timer_cb, os_Timeout, ticks, 0,
228 NU_ENABLE_TIMER);
229 BARRIER;
230 t_list_access = 0;
231 if (sts == NU_SUCCESS)
232 NU_Release_Semaphore(&TimSemCB);
233 return OS_OK;
234 }
235
236 GLOBAL LONG os_StopTimer(OS_HANDLE TaskHandle, OS_HANDLE TimerHandle)
237 /* TaskHandle argument is unused */
238 {
239 T_OS_TIMER_ENTRY *timer_e;
240 STATUS sts;
241
242 if (TimerHandle > MaxSimultaneousTimer)
243 return(OS_ERROR);
244 timer_e = &TimerTable[TimerHandle];
245 sts = NU_Obtain_Semaphore(&TimSemCB, NU_SUSPEND);
246 if (timer_e->entry.status == TMR_FREE) {
247 if (sts == NU_SUCCESS)
248 NU_Release_Semaphore(&TimSemCB);
249 return OS_ERROR;
250 }
251 t_list_access = 1;
252 BARRIER;
253 if (timer_e->entry.status == TMR_ACTIVE)
254 os_remove_timer_from_list(&timer_e->entry);
255 BARRIER;
256 t_list_access = 0;
257 if (sts == NU_SUCCESS)
258 NU_Release_Semaphore(&TimSemCB);
259 return OS_OK;
260 }
261
262 GLOBAL LONG os_IncrementTick(OS_TICK ticks)
263 {
264 return OS_OK;
265 }
266
267 GLOBAL LONG os_DestroyTimer(OS_HANDLE TaskHandle, OS_HANDLE TimerHandle)
268 /* TaskHandle argument is unused */
269 {
270 STATUS sts;
271 T_OS_TIMER_ENTRY *timer_e;
272
273 if (TimerHandle > MaxSimultaneousTimer)
274 return(OS_ERROR);
275 sts = NU_Obtain_Semaphore(&TimSemCB, NU_SUSPEND);
276 timer_e = &TimerTable[TimerHandle];
277 if (timer_e->entry.status != TMR_USED) {
278 if (sts == NU_SUCCESS)
279 NU_Release_Semaphore(&TimSemCB);
280 return OS_ERROR;
281 }
282 timer_e->next_t_handle = next_t_handle;
283 next_t_handle = TimerHandle;
284 timer_e->entry.status = TMR_FREE;
285 used_timers--;
286 if (sts == NU_SUCCESS)
287 NU_Release_Semaphore(&TimSemCB);
288 return OS_OK;
289 }
290
291 GLOBAL LONG os_CreateTimer(OS_HANDLE TaskHandle,
292 void (*TimeoutProc) (OS_HANDLE, OS_HANDLE, USHORT),
293 OS_HANDLE *TimerHandle, OS_HANDLE MemPoolHandle)
294 /* TaskHandle and MemPoolHandle arguments are unused */
295 {
296 STATUS sts;
297 T_OS_TIMER_ENTRY *timer_e;
298
299 sts = NU_Obtain_Semaphore(&TimSemCB, NU_SUSPEND);
300 if (next_t_handle == 0) { /* no free timers left */
301 if (sts == NU_SUCCESS)
302 NU_Release_Semaphore(&TimSemCB);
303 return OS_ERROR;
304 }
305
306 timer_e = &TimerTable[next_t_handle];
307 timer_e->entry.status = TMR_USED;
308 timer_e->entry.TimeoutProc = TimeoutProc;
309 *TimerHandle = next_t_handle;
310 next_t_handle = timer_e->next_t_handle;
311 used_timers++;
312 if (max_used_timers < used_timers)
313 max_used_timers = used_timers;
314 if (sts == NU_SUCCESS)
315 NU_Release_Semaphore(&TimSemCB);
316 return OS_OK;
317 }