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