FreeCalypso > hg > fc-tourmaline
diff src/gpf/osl/os_tim_fl.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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gpf/osl/os_tim_fl.c Fri Oct 16 06:23:26 2020 +0000 @@ -0,0 +1,184 @@ +/* + * This C module is a reconstruction based on the disassembly of + * os_tim.obj in frame_na7_db_fl.lib from the Leonardo package, + * subsequently reworked by Space Falcon. + */ + +/* set of included headers from COFF symtab: */ +#include <stdio.h> +#include "nucleus.h" +#include "typedefs.h" +#include "os.h" +#include "gdi.h" +#include "os_types.h" +#include "os_glob.h" + +extern UNSIGNED TMD_Timer; +extern INT TMD_Timer_State; + +extern T_OS_TIMER_ENTRY TimerTable[]; +extern T_OS_TIMER_TABLE_ENTRY *p_list[]; + +extern void os_Timeout(UNSIGNED t_handle); +extern void timer_error(int err); + +unsigned os_time_to_tick_multiplier = TIME_TO_TICK_TDMA_FRAME_MULTIPLIER; +unsigned os_tick_to_time_multiplier = TICK_TO_TIME_TDMA_FRAME_MULTIPLIER; + +unsigned volatile t_start_ticks; +T_OS_TIMER_TABLE_ENTRY *t_running; +int used_timers; +int next_t_handle; +int volatile t_list_access; +int max_used_timers; +NU_SEMAPHORE TimSemCB; +NU_TIMER os_timer_cb; + +#ifdef __GNUC__ +#define BARRIER asm volatile ("": : :"memory") +#else +#define BARRIER /* prayer */ +#endif + +GLOBAL LONG +os_set_tick(int os_system_tick) +{ + switch (os_system_tick) { + case SYSTEM_TICK_TDMA_FRAME: + os_time_to_tick_multiplier = TIME_TO_TICK_TDMA_FRAME_MULTIPLIER; + os_tick_to_time_multiplier = TICK_TO_TIME_TDMA_FRAME_MULTIPLIER; + return(OS_OK); + case SYSTEM_TICK_10_MS: + os_time_to_tick_multiplier = TIME_TO_TICK_10MS_MULTIPLIER; + os_tick_to_time_multiplier = TICK_TO_TIME_10MS_MULTIPLIER; + return(OS_OK); + default: + return(OS_ERROR); + } +} + +GLOBAL LONG +os_TimerInformation(USHORT Index, char *Buffer) +{ + static int t_info_read; + + if (t_info_read) { + t_info_read = 0; + return(OS_ERROR); + } + sprintf(Buffer, "Maximum %d of %d available timers running", + max_used_timers, MaxSimultaneousTimer); + t_info_read = 1; + return(OS_OK); +} + +GLOBAL LONG +os_TimInit(void) +{ + int i; + + if (NU_Create_Semaphore(&TimSemCB, "TIMSEM", 1, NU_PRIORITY) + != NU_SUCCESS) + return(OS_ERROR); + if (NU_Create_Timer(&os_timer_cb, "OS_TIMER", os_Timeout, 0, 1, 0, + NU_DISABLE_TIMER) != NU_SUCCESS) + return(OS_ERROR); + used_timers = 0; + max_used_timers = 0; + next_t_handle = 1; + t_list_access = 0; + t_start_ticks = 0; + p_list[0] = 0; + for (i = 1; i < MaxSimultaneousTimer; i++) { + TimerTable[i].entry.status = TMR_FREE; + TimerTable[i].entry.next = 0; + TimerTable[i].entry.prev = 0; + TimerTable[i].next_t_handle = i + 1; + p_list[i] = 0; + } + TimerTable[MaxSimultaneousTimer].entry.status = TMR_FREE; + TimerTable[MaxSimultaneousTimer].next_t_handle = 0; + t_running = 0; + return(OS_OK); +} + +GLOBAL LONG +os_RecoverTick(OS_TICK ticks) +{ + UNSIGNED current_system_clock; + + current_system_clock = NU_Retrieve_Clock(); + NU_Set_Clock(current_system_clock + ticks); + if (TMD_Timer_State == TM_ACTIVE) { + if (TMD_Timer <= ticks) { + TMD_Timer_State = TM_EXPIRED; + TMD_Timer = 0; + } else + TMD_Timer -= ticks; + } + return(OS_OK); +} + +GLOBAL LONG +os_QueryTimer(OS_HANDLE TaskHandle, OS_HANDLE TimerHandle, + OS_TIME *RemainingTime) +{ + T_OS_TIMER_TABLE_ENTRY *timer, *t_iter; + OS_TICK c_ticks, r_ticks, e_ticks; + STATUS sts; + + if (TimerHandle > MaxSimultaneousTimer) + return(OS_ERROR); + sts = NU_Obtain_Semaphore(&TimSemCB, NU_SUSPEND); + timer = &TimerTable[TimerHandle].entry; + if (timer->status == TMR_FREE) { + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&TimSemCB); + return(OS_ERROR); + } + t_list_access = 1; + BARRIER; + if (!t_running) { + r_ticks = 0; + goto out; + } + c_ticks = NU_Retrieve_Clock(); + e_ticks = c_ticks - t_start_ticks; + t_iter = t_running; + if (t_iter->r_ticks >= e_ticks) + r_ticks = t_iter->r_ticks - e_ticks; + else + r_ticks = 0; + while (t_iter != timer) { + t_iter = t_iter->next; + if (t_iter == t_running) { + r_ticks = 0; + goto out; + } + r_ticks += t_iter->r_ticks; + } +out: BARRIER; + t_list_access = 0; + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&TimSemCB); + *RemainingTime = SYSTEM_TICKS_TO_TIME(r_ticks); + return(OS_OK); +} + +GLOBAL LONG +os_InactivityTicks(int *next_event, OS_TICK *next_event_ticks) +{ + *next_event = 1; + switch (TMD_Timer_State) { + case TM_ACTIVE: + *next_event_ticks = TMD_Timer; + return(OS_OK); + case TM_NOT_ACTIVE: + *next_event_ticks = 0; + *next_event = 0; + return(OS_OK); + default: + *next_event_ticks = 0; + return(OS_OK); + } +}