# HG changeset patch # User Mychaela Falconia # Date 1529646976 0 # Node ID 91e8dac34adafbc32112171cd395918ac3e46f07 # Parent c433cca731a3dcf5dc00c909ca7d7ed47f318f15 src/gpf2/osl: initial import from old freecalypso-sw tree diff -r c433cca731a3 -r 91e8dac34ada src/gpf2/osl/os_com_fl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gpf2/osl/os_com_fl.c Fri Jun 22 05:56:16 2018 +0000 @@ -0,0 +1,307 @@ +/* + * This C module is a reconstruction based on the disassembly of + * os_com.obj in frame_na7_db_fl.lib from the Leonardo package. + */ + +/* set of included headers from COFF symtab: */ +#include +#include +#include "gpfconf.h" /* FreeCalypso addition */ +#include "../../nucleus/nucleus.h" +#include "typedefs.h" +#include "os.h" +#include "gdi.h" +#include "os_types.h" +#include "os_glob.h" + +extern T_OS_COM_TABLE_ENTRY ComTable[]; + +static NU_SEMAPHORE ComSemCB; + +static int +os_GetQueueEntry(USHORT Index, OS_HANDLE *Handle) +{ + static USHORT Idx; + + if (Index == FIRST_ENTRY) + Idx = 0; + if (Index == FIRST_ENTRY || Index == NEXT_ENTRY) { + while (++Idx <= MaxCommunications && !ComTable[Idx].Name[0]) + ; + } else + Idx = Index; + if (Idx <= MaxCommunications && ComTable[Idx].Name[0]) { + *Handle = Idx; + return(0); + } else + return(-1); +} + +GLOBAL LONG +os_QueueInformation(USHORT Index, char *Buffer) +{ + OS_HANDLE Handle; + T_OS_COM_TABLE_ENTRY *ent; + UNSIGNED Used; + OPTION SuspendType; + UNSIGNED TasksWaiting; + NU_TASK *First; + CHAR Name[NU_MAX_NAME]; + + if (os_GetQueueEntry(Index, &Handle) < 0) + return(OS_ERROR); + ent = ComTable + Handle; + if (NU_Semaphore_Information(&ent->UsedSemCB, Name, &Used, &SuspendType, + &TasksWaiting, &First) != NU_SUCCESS) + return(OS_ERROR); + sprintf(Buffer, "Name:%s Startadr:%lx Entries:%d Used:%ld MaxUsed:%d", + ent->Name, (ULONG)ent->pQueueMemory, ent->Entries, (LONG)Used, + ent->MaxUsed); + return(OS_OK); +} + +GLOBAL LONG +os_OpenQueue(OS_HANDLE TaskHandle, char *Name, OS_HANDLE *ComHandle) +{ + USHORT i; + + if (!Name) + return(OS_ERROR); + for (i = 1; i <= MaxCommunications; i++) + if (ComTable[i].Name[0] && + !strncmp(ComTable[i].Name, Name, RESOURCE_NAMELEN - 1)) { + *ComHandle = i; + return(OS_OK); + } + return(OS_ERROR); +} + +GLOBAL LONG +os_GetQueueState(OS_HANDLE Caller, OS_HANDLE Handle, ULONG *Used, ULONG *Free) +{ + if (ComTable[Handle].Name[0]) { + *Used = ComTable[Handle].UsedSemCB.sm_semaphore_count; + *Free = ComTable[Handle].FreeSemCB.sm_semaphore_count; + return(OS_OK); + } else + return(OS_ERROR); +} + +GLOBAL LONG +os_GetQueueName(OS_HANDLE Caller, OS_HANDLE ComHandle, char *Name) +{ + if (ComHandle > MaxCommunications) + return(OS_ERROR); + if (!ComTable[ComHandle].Name[0]) + return(OS_ERROR); + strcpy(Name, ComTable[ComHandle].Name); + return(OS_OK); +} + +GLOBAL LONG +os_GetQueueHandle(OS_HANDLE Caller, char *Name, OS_HANDLE *ComHandle) +{ + USHORT i; + + for (i = 1; i <= MaxCommunications; i++) + if (ComTable[i].Name[0] && + !strncmp(Name, ComTable[i].Name, RESOURCE_NAMELEN - 1)) { + *ComHandle = i; + return(OS_OK); + } + return(OS_ERROR); +} + +GLOBAL LONG +os_GetQueueData(OS_HANDLE Caller, OS_HANDLE Handle, USHORT Index, USHORT *Type, + ULONG *opc, ULONG *ptr, ULONG *time) +{ + static USHORT entry; + static T_QDATA_ELEMENT *p; + + if (!ComTable[Handle].Name[0]) + return(OS_ERROR); + if (Index == FIRST_ENTRY) { + *Type = ComTable[Handle].current_msg.type; + *opc = ComTable[Handle].current_msg.opc; + *time = ComTable[Handle].current_msg.time; + *ptr = (ULONG) ComTable[Handle].current_msg.ptr; + p = ComTable[Handle].pQueueMemory; + entry = 0; + return(OS_OK); + } + if (entry >= ComTable[Handle].Entries) + return(OS_ERROR); + entry++; + *Type = p->Data.data16; + *ptr = (ULONG) p->Data.ptr; + *opc = p->Data.data32; + *time = p->Data.time; + p++; + return(OS_OK); +} + +GLOBAL unsigned char * +os_FindSuspendingQueue(unsigned int *tcb) +{ + USHORT i; + SM_SUSPEND *susp, *susp2; + + for (i = 1; i <= MaxCommunications; i++) { + if (!ComTable[i].Name[0]) + continue; + if (susp = ComTable[i].FreeSemCB.sm_suspension_list) { + if (susp->sm_suspended_task == (NU_TASK*)tcb) + return(ComTable[i].FreeSemCB.sm_name + 1); + susp = (SM_SUSPEND *) susp->sm_suspend_link.cs_next; + for (susp2 = susp; ; ) { + if (susp2->sm_suspended_task == (NU_TASK*)tcb) + return(ComTable[i].FreeSemCB.sm_name+1); + susp2 = (SM_SUSPEND *) + susp2->sm_suspend_link.cs_next; + if (susp2 == susp) + break; + } + } + if (susp = ComTable[i].UsedSemCB.sm_suspension_list) { + if (susp->sm_suspended_task == (NU_TASK*)tcb) + return(ComTable[i].UsedSemCB.sm_name + 1); + susp = (SM_SUSPEND *) susp->sm_suspend_link.cs_next; + for (susp2 = susp; ; ) { + if (susp2->sm_suspended_task == (NU_TASK*)tcb) + return(ComTable[i].UsedSemCB.sm_name+1); + susp2 = (SM_SUSPEND *) + susp2->sm_suspend_link.cs_next; + if (susp2 == susp) + break; + } + } + } + return(0); +} + +GLOBAL LONG +os_DestroyQueue(OS_HANDLE TaskHandle, OS_HANDLE ComHandle) +{ + STATUS sts; + + sts = NU_Obtain_Semaphore(&ComSemCB, NU_SUSPEND); + if (NU_Delete_Semaphore(&ComTable[ComHandle].FreeSemCB) != NU_SUCCESS) { +return_error: if (sts == NU_SUCCESS) + NU_Release_Semaphore(&ComSemCB); + return(OS_ERROR); + } + if (NU_Delete_Semaphore(&ComTable[ComHandle].UsedSemCB) != NU_SUCCESS) + goto return_error; + if (os_DeallocateMemory(TaskHandle, ComTable[ComHandle].QueueData) + == OS_ERROR) + goto return_error; + ComTable[ComHandle].Name[0] = 0; + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&ComSemCB); + return(OS_OK); +} + +static short +InitQueueMemory(OS_HANDLE TaskHandle, OS_HANDLE ComHandle, USHORT Entries, + OS_HANDLE MemPoolHandle) +{ + T_QDATA_ELEMENT *pElem; + OS_QDATA **ptrs; + USHORT i; + + if (os_AllocateMemory(TaskHandle, &ComTable[ComHandle].QueueData, + sizeof(T_QDATA_ELEMENT) * Entries + + sizeof(OS_QDATA *) * (Entries + 1) + * OS_MAX_PRIORITY, + 0, MemPoolHandle) == OS_TIMEOUT) + return(OS_ERROR); + pElem = (T_QDATA_ELEMENT *) ComTable[ComHandle].QueueData; + ComTable[ComHandle].pQueueMemory = pElem; + ComTable[ComHandle].pFreeElement = pElem; + for (i = 0; i < Entries; i++) { + if (i < Entries - 1) + pElem->pNext = pElem + 1; + else + pElem->pNext = 0; + pElem++; + } + ptrs = (OS_QDATA **) pElem; + for (i = 0; i < OS_MAX_PRIORITY; i++) { + ComTable[ComHandle].Queue[i].pStart = ptrs; + ComTable[ComHandle].Queue[i].pRead = ptrs; + ComTable[ComHandle].Queue[i].pWrite = ptrs; + ptrs += Entries + 1; + } + return(OS_OK); +} + +GLOBAL LONG +os_CreateQueue(OS_HANDLE TaskHandle, OS_HANDLE ComHandle, char *Name, + USHORT Entries, OS_HANDLE *ActHandle, OS_HANDLE MemPoolHandle) +{ + STATUS sts; + OS_HANDLE i; + char Buffer[RESOURCE_NAMELEN + 1]; + + if (os_OpenQueue(TaskHandle, Name, ActHandle) == OS_OK) + return(OS_ERROR); + if (!Entries) + return(OS_ERROR); + sts = NU_Obtain_Semaphore(&ComSemCB, NU_SUSPEND); + if (!ComHandle) { + for (i = 1; i <= MaxCommunications; i++) + if (!ComTable[i].Name[0]) + goto good_slot; +release_sem_error: + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&ComSemCB); + return(OS_ERROR); + } else { + i = ComHandle; + if (i > MaxCommunications) + goto release_sem_error; + if (ComTable[i].Name[0]) + goto release_sem_error; + } +good_slot: + if (InitQueueMemory(TaskHandle, i, Entries, MemPoolHandle) == OS_ERROR) + goto release_sem_error; + strncpy(Buffer + 1, Name, RESOURCE_NAMELEN - 1); + Buffer[RESOURCE_NAMELEN] = 0; + Buffer[0] = 'U'; + if (NU_Create_Semaphore(&ComTable[i].UsedSemCB, Buffer, 0, NU_PRIORITY) + != NU_SUCCESS) + goto release_sem_error; + Buffer[0] = 'F'; + if (NU_Create_Semaphore(&ComTable[i].FreeSemCB, Buffer, Entries, + NU_PRIORITY) != NU_SUCCESS) + goto release_sem_error; + strncpy(ComTable[i].Name, Name, RESOURCE_NAMELEN); + ComTable[i].Name[RESOURCE_NAMELEN-1] = 0; + *ActHandle = i; + ComTable[i].Entries = Entries; + ComTable[i].MaxUsed = 0; + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&ComSemCB); + return(OS_OK); +} + +GLOBAL LONG +os_ComInit(void) +{ + USHORT i; + + if (NU_Create_Semaphore(&ComSemCB, "COMSEM", 1, NU_PRIORITY) + != NU_SUCCESS) + return(OS_ERROR); + for (i = 1; i <= MaxCommunications; i++) + bzero(&ComTable[i], sizeof(T_OS_COM_TABLE_ENTRY)); + return(OS_OK); +} + +GLOBAL LONG +os_CloseQueue(OS_HANDLE TaskHandle, OS_HANDLE ComHandle) +{ + return(OS_OK); +} diff -r c433cca731a3 -r 91e8dac34ada src/gpf2/osl/os_com_ir.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gpf2/osl/os_com_ir.c Fri Jun 22 05:56:16 2018 +0000 @@ -0,0 +1,105 @@ +/* + * This C module is a reconstruction based on the disassembly of + * os_com.obj in frame_na7_db_ir.lib from the Leonardo package. + */ + +/* set of included headers from COFF symtab: */ +#include +#include +#include "gpfconf.h" /* FreeCalypso addition */ +#include "../../nucleus/nucleus.h" +#include "../../nucleus/tc_extr.h" /* not seen in original, but needed */ +#include "typedefs.h" +#include "os.h" +#include "gdi.h" +#include "os_types.h" +#include "os_glob.h" + +extern T_OS_COM_TABLE_ENTRY ComTable[]; +extern unsigned os_tick_to_time_multiplier; + +extern int ObtainSemaphoreCB(NU_SEMAPHORE *SemCB, ULONG Timeout, + USHORT wait_check); +extern int ReleaseSemaphoreCB(NU_SEMAPHORE *SemCB); + +GLOBAL LONG +os_SendToQueue(OS_HANDLE TaskHandle, OS_HANDLE ComHandle, USHORT Priority, + ULONG Suspend, OS_QDATA *Msg) +{ + T_OS_COM_TABLE_ENTRY *pTable; + T_QDATA_ELEMENT *elem; + T_QUEUE *queue; + int ret; + NU_SEMAPHORE *CBPtr; + USHORT watmark; + + if (ComHandle <= 0 || ComHandle > MaxCommunications) + return(OS_INVALID_QUEUE); + pTable = ComTable + ComHandle; + if (!pTable->Name[0]) + return(OS_INVALID_QUEUE); + CBPtr = &pTable->FreeSemCB; + ret = ObtainSemaphoreCB(CBPtr, Suspend, 1); + if (ret == OS_ERROR || ret == OS_TIMEOUT) + return(ret); + TCT_System_Protect(); + elem = pTable->pFreeElement; + pTable->pFreeElement = elem->pNext; + bcopy(Msg, &elem->Data, sizeof(OS_QDATA)); + queue = &pTable->Queue[Priority - OS_MIN_PRIORITY]; + *queue->pWrite++ = &elem->Data; + if (queue->pWrite - queue->pStart >= pTable->Entries + 1) + queue->pWrite = queue->pStart; + watmark = pTable->Entries - CBPtr->sm_semaphore_count; + if (pTable->MaxUsed < watmark) + pTable->MaxUsed = watmark; + TCT_System_Unprotect(); + ReleaseSemaphoreCB(&pTable->UsedSemCB); + return(ret); +} + +GLOBAL LONG +os_ReceiveFromQueue(OS_HANDLE TaskHandle, OS_HANDLE ComHandle, + OS_QDATA *Msg, ULONG Timeout) +{ + T_QDATA_ELEMENT *pElem; + UNSIGNED c_time; + int ret; + USHORT i; + T_QUEUE *pQueue; + T_OS_COM_TABLE_ENTRY *pTable; + + pTable = ComTable + ComHandle; + if (!pTable->Name[0]) + return(OS_ERROR); + pTable->current_msg.type = 0; + ret = ObtainSemaphoreCB(&pTable->UsedSemCB, Timeout, 0); + if (ret == OS_ERROR || ret == OS_TIMEOUT) + return(ret); + TCT_System_Protect(); + for (i = OS_MAX_PRIORITY; i >= OS_MIN_PRIORITY; i--) { + pQueue = &pTable->Queue[i - OS_MIN_PRIORITY]; + if (pQueue->pWrite != pQueue->pRead) + break; + } + if (i < OS_MIN_PRIORITY) { + TCT_System_Unprotect(); + ReleaseSemaphoreCB(&pTable->FreeSemCB); + return(OS_ERROR); + } + bcopy(*pQueue->pRead, Msg, sizeof(OS_QDATA)); + pElem = (T_QDATA_ELEMENT *)*pQueue->pRead++; + pElem->Data.data16 = 0; + pElem->pNext = pTable->pFreeElement; + pTable->pFreeElement = pElem; + if (pQueue->pRead - pQueue->pStart >= pTable->Entries + 1) + pQueue->pRead = pQueue->pStart; + pTable->current_msg.type = Msg->data16; + pTable->current_msg.opc = Msg->data32; + c_time = NU_Retrieve_Clock(); + pTable->current_msg.time = SYSTEM_TICKS_TO_TIME(c_time); + pTable->current_msg.ptr = Msg->ptr; + TCT_System_Unprotect(); + ReleaseSemaphoreCB(&pTable->FreeSemCB); + return(OS_OK); +} diff -r c433cca731a3 -r 91e8dac34ada src/gpf2/osl/os_drv.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gpf2/osl/os_drv.c Fri Jun 22 05:56:16 2018 +0000 @@ -0,0 +1,52 @@ +/* + * This C module is a reconstruction based on the disassembly of + * os_drv.obj in frame_na7_db_fl.lib from the Leonardo package. + */ + +/* set of included headers from COFF symtab: */ +#include "gpfconf.h" /* FreeCalypso addition */ +#include "../../nucleus/nucleus.h" +#include "typedefs.h" +#include "gdi.h" +#include "os.h" + +typedef unsigned char u_char; + +extern OS_HANDLE os_ext_pool_handle; + +static u_char *HISR_Stack; +static T_DRV_SIGNAL *SignalID; +static void (*DrvCallback)(T_DRV_SIGNAL *); +static NU_HISR CallBack_HISR; + +#define CB_HISR_STACK_SIZE 1024 + +GLOBAL LONG +os_ExecuteCallback(OS_HANDLE Caller, void (*Callback)(T_DRV_SIGNAL *), + T_DRV_SIGNAL *Signal) +{ + DrvCallback = Callback; + SignalID = Signal; + NU_Activate_HISR(&CallBack_HISR); + return(OS_OK); +} + +static void +CallbackFunc(void) +{ + DrvCallback(SignalID); +} + +GLOBAL LONG +os_CreateCallback(void) +{ + if (os_AllocateMemory(OS_NOTASK, (T_VOID_STRUCT **) &HISR_Stack, + CB_HISR_STACK_SIZE, 0xFFFFFFFF, + os_ext_pool_handle) == OS_ERROR) + return(OS_ERROR); + if (NU_Create_HISR(&CallBack_HISR, "CB_HISR", CallbackFunc, 2, + HISR_Stack, CB_HISR_STACK_SIZE) == NU_SUCCESS) + return(OS_OK); + else + return(OS_ERROR); +} diff -r c433cca731a3 -r 91e8dac34ada src/gpf2/osl/os_evt.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gpf2/osl/os_evt.c Fri Jun 22 05:56:16 2018 +0000 @@ -0,0 +1,78 @@ +/* + * This C module is a reconstruction based on the disassembly of + * os_evt.obj in frame_na7_db_fl.lib from the Leonardo package. + */ + +/* set of included headers from COFF symtab: */ +#include +#include +#include "gpfconf.h" /* FreeCalypso addition */ +#include "../../nucleus/nucleus.h" +#include "typedefs.h" +#include "os.h" +#include "gdi.h" +#include "os_types.h" +#include "os_glob.h" + +extern T_OS_EVTGRP_TABLE_ENTRY EvtGrpTable[]; + +GLOBAL LONG +os_SetEvents(OS_HANDLE evt_grp_handle, unsigned event_flags) +{ + if (!EvtGrpTable[evt_grp_handle].Name[0]) + return(OS_ERROR); + if (NU_Set_Events(&EvtGrpTable[evt_grp_handle].EvtGrp, event_flags, + NU_OR) == NU_SUCCESS) + return(OS_OK); + else + return(OS_ERROR); +} + +GLOBAL LONG +os_RetrieveEvents(OS_HANDLE evt_grp_handle, unsigned event_flags, char option, + unsigned *retrieved_events, unsigned suspend) +{ + if (!EvtGrpTable[evt_grp_handle].Name[0]) + return(OS_ERROR); + if (NU_Retrieve_Events(&EvtGrpTable[evt_grp_handle].EvtGrp, + event_flags, option, retrieved_events, suspend) + == NU_SUCCESS) + return(OS_OK); + else + return(OS_ERROR); +} + +GLOBAL LONG +os_GetEventGroupHandle(char *evt_grp_name, OS_HANDLE *evt_grp_handle) +{ + int idx; + + for (idx = 0; idx <= MaxEventGroups; idx++) { + if (!EvtGrpTable[idx].Name[0]) + break; + if (!strncmp(EvtGrpTable[idx].Name, evt_grp_name, + RESOURCE_NAMELEN)) + break; + } + if (idx > MaxEventGroups || !EvtGrpTable[idx].Name[0]) { + *evt_grp_handle = -1; + return(OS_ERROR); + } + *evt_grp_handle = idx; + return(OS_OK); +} + +GLOBAL LONG +os_EventGroupInformation(OS_HANDLE evt_grp_handle, char *Name, + unsigned *mask_evt, unsigned *tasks_waiting, + OS_HANDLE *first_task) +{ + if (!EvtGrpTable[evt_grp_handle].Name[0]) + return(OS_ERROR); + if (NU_Event_Group_Information(&EvtGrpTable[evt_grp_handle].EvtGrp, + Name, mask_evt, tasks_waiting, + first_task) == NU_SUCCESS) + return(OS_OK); + else + return(OS_ERROR); +} diff -r c433cca731a3 -r 91e8dac34ada src/gpf2/osl/os_isr.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gpf2/osl/os_isr.c Fri Jun 22 05:56:16 2018 +0000 @@ -0,0 +1,146 @@ +/* + * This C module is a reconstruction based on the disassembly of + * os_isr.obj in frame_na7_db_fl.lib from the Leonardo package. + */ + +/* set of included headers from COFF symtab: */ +#include +#include "gpfconf.h" /* FreeCalypso addition */ +#include "../../nucleus/nucleus.h" +#include "typedefs.h" +#include "os.h" +#include "gdi.h" +#include "os_types.h" +#include "os_glob.h" + +typedef unsigned char u_char; + +extern T_OS_OSISR_TABLE_ENTRY OSISRTable[]; +extern OS_HANDLE os_int_pool_handle; + +GLOBAL LONG +os_isr_init(void) +{ + USHORT i; + + for (i = 1; i <= MaxOSISRs; i++) + OSISRTable[i].name[0] = 0; + return(OS_OK); +} + +GLOBAL LONG +os_SetInterruptState(OS_INT_STATE new_state, OS_INT_STATE *old_state) +{ + INT state; + + if (new_state) + state = NU_ENABLE_INTERRUPTS; + else + state = NU_DISABLE_INTERRUPTS; + state = NU_Control_Interrupts(state); + if (state & 0xFF) + *old_state = 0; + else + *old_state = 1; + return(OS_OK); +} + +GLOBAL LONG +os_EnableInterrupts(OS_INT_STATE *old_state) +{ + INT state; + + state = NU_Control_Interrupts(NU_ENABLE_INTERRUPTS); + if (state & 0xFF) + *old_state = 0; + else + *old_state = 1; + return(OS_OK); +} + +GLOBAL LONG +os_DisableInterrupts(OS_INT_STATE *old_state) +{ + INT state; + + state = NU_Control_Interrupts(NU_DISABLE_INTERRUPTS); + if (state & 0xFF) + *old_state = 0; + else + *old_state = 1; + return(OS_OK); +} + +GLOBAL LONG +os_DeleteOSISR(OS_HANDLE hisr_handle) +{ + OS_INT_STATE old_state, state; + + if (hisr_handle <= 0 || hisr_handle > MaxOSISRs) + return(OS_ERROR); + if (OSISRTable[hisr_handle].hisr_cb.tc_activation_count) + return(OS_ERROR); + os_DisableInterrupts(&old_state); + if (os_DeallocateMemory(os_MyHandle(), OSISRTable[hisr_handle].stack) + == OS_ERROR) { +error: os_SetInterruptState(old_state, &state); + return(OS_ERROR); + } + if (NU_Delete_HISR(&OSISRTable[hisr_handle].hisr_cb) != NU_SUCCESS) + goto error; + OSISRTable[hisr_handle].name[0] = 0; + os_SetInterruptState(old_state, &state); + return(OS_OK); +} + +GLOBAL LONG +os_CreateOSISR(char *name, void (*OSISR_entry)(void), + int stacksize, int priority, + int flags, OS_HANDLE *hisr_handle) +{ + OS_HANDLE handle; + T_VOID_STRUCT *hisr_stack; + OS_INT_STATE old_state, state; + + if (priority < 0 || priority > 2) + return(OS_ERROR); + priority = 2 - priority; + os_DisableInterrupts(&old_state); + for (handle = 1; handle <= MaxOSISRs; handle++) + if (!strncmp(OSISRTable[handle].name, name, + RESOURCE_NAMELEN - 1)) { +error: os_SetInterruptState(old_state, &state); + return(OS_ERROR); + } + for (handle = 1; handle <= MaxOSISRs; handle++) + if (!OSISRTable[handle].name[0]) + break; + if (handle > MaxOSISRs) + goto error; + if (os_AllocateMemory(os_MyHandle(), &hisr_stack, stacksize, + 0xFFFFFFFF, os_int_pool_handle) == OS_ERROR) + goto error; + memset((u_char *)hisr_stack, INITIAL_STACK_VALUE, stacksize); + *hisr_stack = GUARD_PATTERN; + if (NU_Create_HISR(&OSISRTable[handle].hisr_cb, name, OSISR_entry, + priority, (VOID *)hisr_stack, stacksize) + != NU_SUCCESS) + goto error; + strncpy(OSISRTable[handle].name, name, RESOURCE_NAMELEN); + OSISRTable[handle].name[RESOURCE_NAMELEN-1] = 0; + OSISRTable[handle].stack = hisr_stack; + *hisr_handle = handle; + os_SetInterruptState(old_state, &state); + return(OS_OK); +} + +GLOBAL LONG +os_ActivateOSISR(OS_HANDLE hisr_handle) +{ + if (hisr_handle <= 0 || hisr_handle > MaxOSISRs) + return(OS_ERROR); + if (NU_Activate_HISR(&OSISRTable[hisr_handle].hisr_cb) == NU_SUCCESS) + return(OS_OK); + else + return(OS_ERROR); +} diff -r c433cca731a3 -r 91e8dac34ada src/gpf2/osl/os_mem_fl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gpf2/osl/os_mem_fl.c Fri Jun 22 05:56:16 2018 +0000 @@ -0,0 +1,440 @@ +/* + * This C module is a reconstruction based on the disassembly of + * os_mem.obj in frame_na7_db_fl.lib from the Leonardo package. + */ + +/* set of included headers from COFF symtab: */ +#include +#include +#include "gpfconf.h" /* FreeCalypso addition */ +#include "../../nucleus/nucleus.h" +#include "typedefs.h" +#include "os.h" +#include "gdi.h" +#include "os_types.h" +#include "os_glob.h" + +extern T_OS_PART_GRP_TABLE_ENTRY PartGrpTable[]; +extern T_OS_MEM_POOL_TABLE_ENTRY MemPoolTable[]; +extern T_OS_POOL_BORDER PoolBorder[]; + +OS_HANDLE os_ext_pool_handle; +OS_HANDLE os_int_pool_handle; + +static USHORT NumOfMemoryPools; +static NU_SEMAPHORE MemSemCB; +static NU_MEMORY_POOL mem_pool_head; + +GLOBAL LONG +os_SetPoolHandles(OS_HANDLE ext_pool_handle, OS_HANDLE int_pool_handle) +{ + os_ext_pool_handle = ext_pool_handle; + os_int_pool_handle = int_pool_handle; + return(OS_OK); +} + +static int +os_GetPartitionPoolEntry(USHORT Index, T_OS_PART_POOL **pool) +{ + static T_OS_PART_POOL *part_pool; + static int grp_hndl; + + switch (Index) { + case FIRST_ENTRY: + grp_hndl = 0; + *pool = part_pool = PartGrpTable[0].grp_head; + return(OS_OK); + case NEXT_ENTRY: + if (part_pool->next) { + *pool = part_pool = part_pool->next; + return(OS_OK); + } + grp_hndl++; + if (PartGrpTable[grp_hndl].grp_head) { + *pool = part_pool = PartGrpTable[grp_hndl].grp_head; + return(OS_OK); + } else + return(OS_ERROR); + default: + return(OS_ERROR); + } +} + +GLOBAL LONG +os_PartitionInformation(USHORT Handle, char *Buffer) +{ + T_OS_PART_POOL *pool; + OPTION SuspendType; + UNSIGNED PoolSize; + UNSIGNED PartitionSize; + UNSIGNED Available; + UNSIGNED Waiting; + UNSIGNED Allocated; + VOID *pStartAddress; + NU_TASK *First; + CHAR Name[NU_MAX_NAME]; + + if (os_GetPartitionPoolEntry(Handle, &pool) == OS_ERROR) + return(OS_ERROR); + if (NU_Partition_Pool_Information(&pool->pcb, Name, &pStartAddress, + &PoolSize, &PartitionSize, &Available, + &Allocated, &SuspendType, &Waiting, + &First) + != NU_SUCCESS) + return(OS_ERROR); + sprintf(Buffer, + "Name:%s Addr:%lx PoolSize:%ld PartSize:%ld Free:%ld Used:%ld", + Name, (UNSIGNED) pStartAddress, PoolSize, PartitionSize, + Available, Allocated); + return(OS_OK); +} + +static int +os_GetMemoryPoolEntry(USHORT Index, OS_HANDLE *Handle) +{ + static USHORT Idx; + + switch (Index) { + case FIRST_ENTRY: + Idx = 0; + break; + case NEXT_ENTRY: + Idx++; + break; + default: + Idx = Index; + } + if (Idx == NumOfMemoryPools) + return(OS_ERROR); + *Handle = Idx; + return(OS_OK); +} + +GLOBAL LONG +os_MemoryInformation(USHORT Index, char *Buffer) +{ + OS_HANDLE Handle; + OPTION SuspendType; + UNSIGNED Size, Min, Available, Waiting; + VOID *pStartAddress; + NU_TASK *First; + CHAR Name[NU_MAX_NAME]; + + if (os_GetMemoryPoolEntry(Index, &Handle) == OS_ERROR) + return(OS_ERROR); + if (NU_Memory_Pool_Information(MemPoolTable[Handle].pcb, Name, + &pStartAddress, &Size, &Min, + &Available, &SuspendType, &Waiting, + &First) + != NU_SUCCESS) + return(OS_ERROR); + sprintf(Buffer, + "Heapname:%s Addr:%lx Size:%ld Min:%ld Free:%ld Suspend:%d", + Name, (UNSIGNED) pStartAddress, Size, Min, Available, + SuspendType); + return(OS_OK); +} + +GLOBAL LONG +os_MemInit(void) +{ + USHORT i; + + if (NU_Create_Semaphore(&MemSemCB, "MEMSEM", 1, NU_PRIORITY) + != NU_SUCCESS) + return(OS_ERROR); + for (i = 0; i <= MaxPoolGroups; i++) { + PoolBorder[i].Start = (char *)0xFFFFFFFF; + PoolBorder[i].End = (char *)0; + PartGrpTable[i].grp_head = 0; + PartGrpTable[i].name[0] = 0; + } + MemPoolTable[0].pcb = &mem_pool_head; + return(OS_OK); +} + +void +os_InitPartitionCheck(T_OS_PART_POOL *pool) +{ + unsigned **Buffer, offset; + USHORT i, k; + + NU_Allocate_Memory(MemPoolTable[0].pcb, (VOID **) &Buffer, + pool->pcb.pm_available * sizeof(unsigned *), + NU_NO_SUSPEND); + offset = pool->pcb.pm_partition_size / sizeof(unsigned) - 1; + for (i = 0; ; i++) { + if (NU_Allocate_Partition(&pool->pcb, (VOID **)(Buffer + i), + NU_NO_SUSPEND) + != NU_SUCCESS) + break; + Buffer[i][offset] = GUARD_PATTERN; + } + for (k = 0; k < i; k++) + if (NU_Deallocate_Partition(Buffer[k]) != NU_SUCCESS) + break; + NU_Deallocate_Memory(Buffer); +} + +GLOBAL const ULONG * +os_GetPrimpoolCB(int grp, int id) +{ + T_OS_PART_POOL *pool; + int i; + + pool = PartGrpTable[grp].grp_head; + if (!pool) + return(0); + if (id < 0) + return(0); + for (i = 0; i < id; i++) { + pool = pool->next; + if (!pool) + return(0); + } + return (const ULONG *) &pool->pcb; +} + +GLOBAL LONG +os_GetPartitionPoolStatus(ULONG size, OS_HANDLE gr_hndl, + USHORT *m_free, USHORT *m_alloc) +{ + T_OS_PART_POOL *pool; + UNSIGNED dummy, allocated, available; + CHAR Name[NU_MAX_NAME]; + + for (pool = PartGrpTable[gr_hndl].grp_head; pool; pool = pool->next) { + if (!size) + break; + if (size > pool->size) + continue; + if (NU_Partition_Pool_Information(&pool->pcb, Name, + (VOID **)&dummy, &dummy, + &dummy, &available, + &allocated, (OPTION *)&dummy, + &dummy, (NU_TASK **)&dummy) + != NU_SUCCESS) + break; + *m_alloc = allocated; + *m_free = available; + return(OS_OK); + } + *m_alloc = 0; + *m_free = 0; + return(OS_ERROR); +} + +GLOBAL LONG +os_GetPartitionGroupHandle(OS_HANDLE Caller, char *Name, OS_HANDLE *GroupHandle) +{ + int i; + + for (i = 0; i <= MaxPoolGroups; i++) { + if (!PartGrpTable[i].grp_head) + continue; + if (strncmp(Name, PartGrpTable[i].name, RESOURCE_NAMELEN-1)) + continue; + *GroupHandle = i; + return(OS_OK); + } + return(OS_ERROR); +} + +GLOBAL LONG +os_DeallocateMemory(OS_HANDLE TaskHandle, T_VOID_STRUCT *Buffer) +{ + if (NU_Deallocate_Memory(Buffer) == NU_SUCCESS) + return(OS_OK); + else + return(OS_ERROR); +} + +GLOBAL LONG +os_AllocateMemory(OS_HANDLE TaskHandle, T_VOID_STRUCT **Buffer, ULONG Size, + ULONG Suspend, OS_HANDLE PoolHandle) +{ + int ret, sts; + + if (Suspend == 0xFFFFFFFF) + Suspend = 1; + ret = OS_OK; + for (;;) { + sts = NU_Allocate_Memory(MemPoolTable[PoolHandle].pcb, Buffer, + Size, Suspend); + switch (sts) { + case NU_SUCCESS: + return(ret); + case NU_INVALID_SUSPEND: + Suspend = 0; + continue; + case NU_NO_MEMORY: + case NU_TIMEOUT: + if (Suspend == 1) { + Suspend = 0xFFFFFFFF; + ret = OS_WAITED; + continue; + } else { + *Buffer = 0; + return(OS_TIMEOUT); + } + default: + /* + * Disassembly reveals that the original code + * has an endless loop here, the equivalent + * of continue. My guess is that they simply + * forgot the default case, and so control + * falls onto the closing brace of the switch + * and then onto the closing brace of the for + * loop. But I prefer better error handling, + * hence the present addition. - Space Falcon + */ + *Buffer = 0; + return(OS_ERROR); + } + } +} + +GLOBAL LONG +os_CreatePartitionPool(OS_HANDLE TaskHandle, char *GroupName, void *Addr, + USHORT Num, ULONG Size, OS_HANDLE *GroupHandle) +{ + STATUS sts; + T_OS_PART_POOL *part_group_head, *opool, *npool; + USHORT part_group; + USHORT i, j; + char PoolName[8], *cp; + + sts = NU_Obtain_Semaphore(&MemSemCB, NU_SUSPEND); + j = 0; + part_group_head = 0; + for (i = 0; i <= MaxPoolGroups; i++) { + if (!PartGrpTable[i].grp_head || !PartGrpTable[i].name[0]) + break; + if (!strncmp(GroupName, PartGrpTable[i].name, + RESOURCE_NAMELEN - 1)) { + part_group_head = PartGrpTable[i].grp_head; + opool = part_group_head; + j++; + while (opool->next) { + opool = opool->next; + j++; + } + break; + } + } + /* + * This error check logic has been modified from the original + * faithful reconstruction by Space Falcon. In the original code + * if MaxPoolGroups had been reached and the for loop above + * never broke, the code would proceed to overwrite pool #0 + * instead of catching the error. + */ + if (i > MaxPoolGroups) { +release_sem_return_err: + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&MemSemCB); + return(OS_ERROR); + } + part_group = i; + if (!part_group_head) { + strncpy(PartGrpTable[part_group].name, GroupName, + RESOURCE_NAMELEN); + PartGrpTable[part_group].name[RESOURCE_NAMELEN-1] = 0; + } + if (os_AllocateMemory(OS_NOTASK, (T_VOID_STRUCT **) &npool, + sizeof(T_OS_PART_POOL), OS_NO_SUSPEND, + os_ext_pool_handle) != OS_OK) + goto release_sem_return_err; + sprintf(PoolName, "POOL%1d%1d", part_group + 1, j); + Size &= ~3; + npool->pool_mem = Addr; + /* + * FreeCalypso: we need to bzero the PM_PCB before calling + * NU_Create_Partition_Pool() to prevent the possibility of + * Nucleus error checker failing the call because the + * signature word happens to be there already. + */ + bzero(&npool->pcb, sizeof(NU_PARTITION_POOL)); + if (NU_Create_Partition_Pool(&npool->pcb, PoolName, npool->pool_mem, + POOL_SIZE(Num, Size), Size + 4, NU_FIFO) + != NU_SUCCESS) + goto release_sem_return_err; + if (!part_group_head) + PartGrpTable[part_group].grp_head = npool; + else + opool->next = npool; + npool->size = Size; + npool->next = 0; + *GroupHandle = part_group; + cp = (char *) npool->pool_mem; + if (PoolBorder[part_group].Start >= cp) + PoolBorder[part_group].Start = cp; + cp += POOL_SIZE(Num, Size); + if (PoolBorder[part_group].End < cp) + PoolBorder[part_group].End = cp; + os_InitPartitionCheck(npool); + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&MemSemCB); + return(OS_OK); +} + +GLOBAL LONG +os_CreatePartitionPool_fixed_pool_size(OS_HANDLE TaskHandle, char *GroupName, + void *Addr, USHORT PoolSize, + ULONG PartSize, OS_HANDLE *GroupHandle, + ULONG *NumCreated) +{ + USHORT num; + + num = PoolSize / (PartSize + PT_CHKOVERHEAD + PT_OVERHEAD); + *NumCreated = num; + return os_CreatePartitionPool(TaskHandle, GroupName, Addr, num, + PartSize, GroupHandle); +} + +GLOBAL LONG +os_CreateMemoryPool(OS_HANDLE TaskHandle, char *Name, void *Addr, + ULONG PoolSize, OS_HANDLE *PoolHandle) +{ + STATUS sts; + USHORT i; + + sts = NU_Obtain_Semaphore(&MemSemCB, NU_SUSPEND); + for (i = 0; i < NumOfMemoryPools; i++) + if (!strncmp(Name, MemPoolTable[i].name, RESOURCE_NAMELEN-1)) { + *PoolHandle = i; + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&MemSemCB); + return(OS_OK); + } + if (i >= MaxMemoryPools) { +release_sem_return_err: + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&MemSemCB); + return(OS_ERROR); + } + if (i) { + if (os_AllocateMemory(OS_NOTASK, + (T_VOID_STRUCT **) &MemPoolTable[i].pcb, + sizeof(NU_MEMORY_POOL), OS_NO_SUSPEND, + os_ext_pool_handle) != OS_OK) + goto release_sem_return_err; + /* + * FreeCalypso: we need to bzero the DM_PCB before calling + * NU_Create_Memory_Pool() to prevent the possibility of + * Nucleus error checker failing the call because the + * signature word happens to be there already. + */ + bzero(MemPoolTable[i].pcb, sizeof(NU_MEMORY_POOL)); + } + if (NU_Create_Memory_Pool(MemPoolTable[i].pcb, Name, Addr, PoolSize, + 4, NU_FIFO) != NU_SUCCESS) + goto release_sem_return_err; + strncpy(MemPoolTable[i].name, Name, RESOURCE_NAMELEN); + MemPoolTable[i].name[RESOURCE_NAMELEN-1] = 0; + *PoolHandle = i; + NumOfMemoryPools++; + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&MemSemCB); + return(OS_OK); +} diff -r c433cca731a3 -r 91e8dac34ada src/gpf2/osl/os_mem_ir.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gpf2/osl/os_mem_ir.c Fri Jun 22 05:56:16 2018 +0000 @@ -0,0 +1,107 @@ +/* + * This C module is a reconstruction based on the disassembly of + * os_mem.obj in frame_na7_db_ir.lib from the Leonardo package. + */ + +/* set of included headers from COFF symtab: */ +#include +#include +#include "gpfconf.h" /* FreeCalypso addition */ +#include "../../nucleus/nucleus.h" +#include "typedefs.h" +#include "os.h" +#include "gdi.h" +#include "os_types.h" +#include "os_glob.h" + +extern T_OS_PART_GRP_TABLE_ENTRY PartGrpTable[]; +extern T_OS_POOL_BORDER PoolBorder[]; + +GLOBAL LONG +os_is_valid_partition(T_VOID_STRUCT *Buffer) +{ + int i; + + for (i = 0; i <= MaxPoolGroups; i++) { + if (PoolBorder[i].End == 0) + return(OS_ERROR); + if ((char *)Buffer < PoolBorder[i].Start) + continue; + if ((char *)Buffer >= PoolBorder[i].End) + continue; + return(OS_OK); + } + return(OS_ERROR); +} + +GLOBAL LONG +os_PartitionCheck(ULONG *ptr) +{ + PM_HEADER *phdr; + PM_PCB *pool; + + phdr = (PM_HEADER *)(ptr - 2); + if (phdr->pm_next_available) + return(OS_PARTITION_FREE); + pool = phdr->pm_partition_pool; + if (ptr[(pool->pm_partition_size - 4) >> 2] == GUARD_PATTERN) + return(OS_OK); + else + return(OS_PARTITION_GUARD_PATTERN_DESTROYED); +} + +GLOBAL LONG +os_DeallocatePartition(OS_HANDLE TaskHandle, T_VOID_STRUCT *Buffer) +{ + if (os_is_valid_partition(Buffer) != OS_OK) + return(OS_ERROR); + if (NU_Deallocate_Partition(Buffer) != NU_SUCCESS) + return(OS_ERROR); + return(OS_OK); +} + +GLOBAL LONG +os_AllocatePartition(OS_HANDLE TaskHandle, T_VOID_STRUCT **Buffer, ULONG Size, + ULONG Suspend, OS_HANDLE GroupHandle) +{ + T_OS_PART_POOL *pool, *requested_pool; + ULONG nu_suspend; + STATUS sts; + int ret; + + for (pool = PartGrpTable[GroupHandle].grp_head; pool; + pool = pool->next) + if (Size <= pool->size) + break; + if (!pool) + return(OS_ERROR); + requested_pool = pool; + ret = OS_OK; + nu_suspend = NU_NO_SUSPEND; +try_alloc: + sts = NU_Allocate_Partition(&pool->pcb, (VOID **) Buffer, nu_suspend); + switch (sts) { + case NU_SUCCESS: + return(ret); + case NU_TIMEOUT: + case NU_INVALID_SUSPEND: + *Buffer = 0; + return(OS_TIMEOUT); + case NU_NO_PARTITION: + pool = pool->next; + if (pool) { + ret = OS_ALLOCATED_BIGGER; + goto try_alloc; + } + pool = requested_pool; + if (Suspend) { + nu_suspend = Suspend; + ret = OS_WAITED; + goto try_alloc; + } + return(OS_TIMEOUT); + default: + *Buffer = 0; + return(OS_ERROR); + } +} diff -r c433cca731a3 -r 91e8dac34ada src/gpf2/osl/os_mis_fl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gpf2/osl/os_mis_fl.c Fri Jun 22 05:56:16 2018 +0000 @@ -0,0 +1,162 @@ +/* + * This C module is a reconstruction based on the disassembly of + * os_mis.obj in frame_na7_db_fl.lib from the Leonardo package. + */ + +/* set of included headers from COFF symtab, slightly reordered: */ +#include +#include +#include +#include "../../riviera/rv/general.h" +#include "../../riviera/rv/rv_general.h" +#include "../../riviera/rvf/rvf_api.h" +#include "../../services/ffs/ffs.h" +#include "gpfconf.h" /* FreeCalypso addition */ +#include "../../nucleus/nucleus.h" +#include "typedefs.h" +#include "os.h" +#include "gdi.h" +#include "os_types.h" +#include "os_glob.h" +#include "header.h" +#include "vsi.h" +#include "drvconf.h" +#include "../tst_pei/tstdriver.h" +#include "dar_func.h" +#include "tools.h" + +typedef unsigned char u_char; + +char *NU_State[13] = { + "NU_READY", + "", + "NU_SLEEP_SUSPEND", + "", + "", + "NU_QUEUE_SUSPEND", + "NU_SEMAPHORE_SUSPEND", + "", + "NU_PARTITION_SUSPEND", + "NU_MEMORY_SUSPEND", + "", + "NU_FINISHED", + "NU_TERMINATED", +}; + +char *msg_type[4] = { + "", + "PRIMITIVE", + "SIGNAL", + "TIMEOUT", +}; + +char *warning = "SYSTEM WARNING: "; + +T_GPF_DAR_PROPERTIES *dar; +T_GPF_DAR_STRUCT os_dar; +NU_PROTECT os_mis_Protect; +u_char SystemErrorBuffer[256]; +u_char DARErrorBuffer[256]; + +static u_char state; +static int fd; +static unsigned bytes_read; +static u_char *msg; +static unsigned count; +static unsigned data_len; +static unsigned dar_wrap_around; +static unsigned dar_buffer_count; +static unsigned dar_wrap_around_detected; + +LONG +os_read_dar_ffs_data(USHORT entry, char *buffer, USHORT len) +{ + /* dummy for now */ + return(OS_ERROR); +} + +LONG +os_dar_set_filter(void) +{ + if (dar) + dar->diagnose_swe_filter(dar->gpf_use_id, dar->warning); + return(OS_OK); +} + +LONG +os_dar_register(const void *dar_properties) +{ + if (dar_properties) { + os_dar.properties = (T_GPF_DAR_PROPERTIES *) dar_properties; + os_dar.magic_nr = DAR_INITIALIZED; + dar = (T_GPF_DAR_PROPERTIES *) dar_properties; + } + return(OS_OK); +} + +void +os_dar_init(void) +{ + if (os_dar.magic_nr != DAR_INITIALIZED) + dar = 0; +} + +void +os_SystemError(OS_HANDLE Caller, USHORT cause, char *buffer) +{ + /* + * The implementation of this function in the binary blob + * which we are reversing is very complex. I am leaving it + * as an empty stub for now. - Space Falcon + */ +} + +GLOBAL LONG +os_ObjectInformation(OS_HANDLE Caller, USHORT Id, USHORT Handle, USHORT len, + void *Buffer) +{ + switch (Id) { + case OS_OBJTASK: + return os_TaskInformation(Handle, Buffer); + case OS_OBJQUEUE: + return os_QueueInformation(Handle, Buffer); + case OS_OBJPARTITIONGROUP: + return os_PartitionInformation(Handle, Buffer); + case OS_OBJMEMORYPOOL: + return os_MemoryInformation(Handle, Buffer); + case OS_OBJTIMER: + return os_TimerInformation(Handle, Buffer); + case OS_OBJSEMAPHORE: + return os_SemaphoreInformation(Handle, Buffer); + default: + return(OS_ERROR); + } +} + +GLOBAL LONG +os_Initialize(void) +{ + if (os_SemInit() == OS_ERROR) + return(OS_ERROR); + if (os_ProInit() == OS_ERROR) + return(OS_ERROR); + if (os_ComInit() == OS_ERROR) + return(OS_ERROR); + if (os_MemInit() == OS_ERROR) + return(OS_ERROR); + if (os_TimInit() == OS_ERROR) + return(OS_ERROR); + if (os_isr_init() == OS_ERROR) + return(OS_ERROR); +#if 0 + if (os_EvGrpInit() == OS_ERROR) + return(OS_ERROR); +#endif + /* + * The original code zeroes out the first 32-bit word of + * os_mis_Protect here. We don't really need to do that, + * as it is a zeroed-on-boot bss var. + */ + os_dar_init(); /* inlined in the original */ + return(OS_OK); +} diff -r c433cca731a3 -r 91e8dac34ada src/gpf2/osl/os_mis_ir.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gpf2/osl/os_mis_ir.c Fri Jun 22 05:56:16 2018 +0000 @@ -0,0 +1,25 @@ +/* + * This C module is a reconstruction based on the disassembly of + * os_mis.obj in frame_na7_db_ir.lib from the Leonardo package. + */ + +/* subset of included headers from COFF symtab: */ +#include "gpfconf.h" /* FreeCalypso addition */ +#include "../../nucleus/nucleus.h" +#include "typedefs.h" +#include "os.h" +#include "gdi.h" +#include "os_types.h" +#include "os_glob.h" + +extern unsigned os_tick_to_time_multiplier; + +GLOBAL LONG +os_GetTime(OS_HANDLE Caller, OS_TIME *Time) +{ + UNSIGNED Value; + + Value = NU_Retrieve_Clock(); + *Time = SYSTEM_TICKS_TO_TIME(Value); + return(OS_OK); +} diff -r c433cca731a3 -r 91e8dac34ada src/gpf2/osl/os_pro_fl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gpf2/osl/os_pro_fl.c Fri Jun 22 05:56:16 2018 +0000 @@ -0,0 +1,237 @@ +/* + * This C module is a reconstruction based on the disassembly of + * os_pro.obj in frame_na7_db_fl.lib from the Leonardo package. + */ + +/* set of included headers from COFF symtab: */ +#include +#include +#include "gpfconf.h" /* FreeCalypso addition */ +#include "../../nucleus/nucleus.h" +#include "typedefs.h" +#include "os.h" +#include "gdi.h" +#include "os_types.h" +#include "os_glob.h" + +typedef unsigned char u_char; + +extern VOID *TCD_Current_Thread; +extern T_OS_TASK_TABLE_ENTRY TaskTable[]; +extern VOID os_TaskEntry(UNSIGNED, VOID *); + +static NU_SEMAPHORE ProSemCB; + +#define OS_NU_TASK_MAGIC 0xdeafbeef + +static int +os_GetTaskEntry(USHORT Index, OS_HANDLE *Handle) +{ + static USHORT Idx; + + if (Index == FIRST_ENTRY) + Idx = 0; + if (Index == FIRST_ENTRY || Index == NEXT_ENTRY) { + while (++Idx <= MaxTasks && !TaskTable[Idx].Name[0]) + ; + } else + Idx = Index; + if (Idx <= MaxTasks && TaskTable[Idx].Name[0]) { + *Handle = Idx; + return(0); + } else + return(-1); +} + +GLOBAL LONG +os_TaskInformation(USHORT Index, char *Buffer) +{ + DATA_ELEMENT TaskStatus; + OPTION Prio, Preempt; + UNSIGNED Count, TimeSlice, Size, MinStack; + OS_HANDLE Handle; + CHAR Name[NU_MAX_NAME]; + u_char *StackBase, *sp; + USHORT Untouched; + + if (os_GetTaskEntry(Index, &Handle) < 0) + return(OS_ERROR); + if (NU_Task_Information(&TaskTable[Handle].TaskCB.TCB, Name, + &TaskStatus, &Count, &Prio, &Preempt, + &TimeSlice, (VOID **) &StackBase, + &Size, &MinStack) != NU_SUCCESS) + return(OS_ERROR); + Untouched = 0; + for (sp = StackBase; sp < StackBase + Size; sp++) { + if (*sp != INITIAL_STACK_VALUE) + break; + Untouched++; + } + sprintf(Buffer, + "Name:%s Stat:%d Count:%ld Prio:%d Stack:%lx Size:%ld Untouched:%d", + Name, TaskStatus, Count, 255 - Prio, (ULONG) StackBase, + (LONG) Size, Untouched); + return(OS_OK); +} + +GLOBAL LONG +os_StopTask(OS_HANDLE Caller, OS_HANDLE TaskHandle) +{ + if (NU_Suspend_Task(&TaskTable[TaskHandle].TaskCB.TCB) == NU_SUCCESS) + return(OS_OK); + else + return(OS_ERROR); +} + +GLOBAL LONG +os_StartTask(OS_HANDLE Caller, OS_HANDLE TaskHandle, ULONG Value) +{ + if (NU_Resume_Task(&TaskTable[TaskHandle].TaskCB.TCB) == NU_SUCCESS) + return(OS_OK); + else + return(OS_ERROR); +} + +GLOBAL LONG +os_ProInit(void) +{ + USHORT i; + + if (NU_Create_Semaphore(&ProSemCB, "PROSEM", 1, NU_PRIORITY) + != NU_SUCCESS) + return(OS_ERROR); + for (i = 1; i <= MaxTasks; i++) + bzero(&TaskTable[i], sizeof(T_OS_TASK_TABLE_ENTRY)); + return(OS_OK); +} + +GLOBAL unsigned char +os_GetTaskState(OS_HANDLE Caller, OS_HANDLE Handle) +{ + if (TaskTable[Handle].Name[0]) + return(TaskTable[Handle].TaskCB.TCB.tc_status); + else + return(255); +} + +GLOBAL LONG +os_GetTaskHandle(OS_HANDLE Caller, char *Name, OS_HANDLE *TaskHandle) +{ + USHORT i; + + if (!Name) { + OS_NU_TASK *os_nu_task = (OS_NU_TASK *) TCD_Current_Thread; + + if (os_nu_task && os_nu_task->magic_nr == OS_NU_TASK_MAGIC) + *TaskHandle = os_nu_task->handle; + else + *TaskHandle = OS_NOTASK; + return(OS_OK); + } + for (i = 1; i <= MaxTasks; i++) + if (TaskTable[i].Name[0] && + !strncmp(Name, TaskTable[i].Name, RESOURCE_NAMELEN - 1)) { + *TaskHandle = i; + return(OS_OK); + } + return(OS_ERROR); +} + +GLOBAL LONG +os_GetTaskData(OS_HANDLE Handle, unsigned **tcb, + u_char **stackbegin, u_char **stackend) +{ + NU_TASK *task; + + if (!TaskTable[Handle].Name[0]) + return(OS_ERROR); + task = &TaskTable[Handle].TaskCB.TCB; + *tcb = (unsigned *) task; + *stackbegin = (u_char *) task->tc_stack_start; + *stackend = (u_char *) task->tc_stack_end; + return(OS_OK); +} + +GLOBAL LONG +os_GetScheduleCount(OS_HANDLE task_handle, int *schedule_count) +{ + NU_TASK *task_cb; + + if (task_handle > MaxTasks) + return(OS_ERROR); + if (!TaskTable[task_handle].Name[0]) + return(OS_ERROR); + if (task_handle == OS_NOTASK) + task_cb = (NU_TASK *) TCD_Current_Thread; + else + task_cb = &TaskTable[task_handle].TaskCB.TCB; + *schedule_count = task_cb->tc_scheduled; + return(OS_OK); +} + +GLOBAL LONG +os_DestroyTask(OS_HANDLE Caller, OS_HANDLE TaskHandle) +{ + STATUS sts; + + if (NU_Terminate_Task(&TaskTable[TaskHandle].TaskCB.TCB) != NU_SUCCESS) + return(OS_ERROR); + if (NU_Delete_Task(&TaskTable[TaskHandle].TaskCB.TCB) != NU_SUCCESS) + return(OS_ERROR); + if (os_DeallocateMemory(Caller, TaskTable[TaskHandle].Stack) != OS_OK) + return(OS_ERROR); + sts = NU_Obtain_Semaphore(&ProSemCB, NU_SUSPEND); + TaskTable[TaskHandle].Name[0] = 0; + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&ProSemCB); + return(OS_OK); +} + +GLOBAL LONG +os_CreateTask(OS_HANDLE Caller, char *Name, + void (*TaskEntry)(OS_HANDLE, ULONG), ULONG StackSize, + USHORT Priority, OS_HANDLE *TaskHandle, OS_HANDLE MemPoolHandle) +{ + STATUS sem_sts; + USHORT Handle; + u_char *stack; + + sem_sts = NU_Obtain_Semaphore(&ProSemCB, NU_SUSPEND); + for (Handle = 1; Handle <= MaxTasks; Handle++) + if (!TaskTable[Handle].Name[0]) + break; + if (Handle > MaxTasks) { +return_error: if (sem_sts == NU_SUCCESS) + NU_Release_Semaphore(&ProSemCB); + return(OS_ERROR); + } + if (os_AllocateMemory(Handle, &TaskTable[Handle].Stack, StackSize + 4, + 0, MemPoolHandle) != OS_OK) + goto return_error; + stack = (u_char *)TaskTable[Handle].Stack + 4; + memset(stack, INITIAL_STACK_VALUE, StackSize); + *TaskTable[Handle].Stack = GUARD_PATTERN; + if (NU_Create_Task(&TaskTable[Handle].TaskCB.TCB, Name, os_TaskEntry, + Handle, 0, stack, StackSize, + 255 - Priority, 0, NU_PREEMPT, NU_NO_START) + != NU_SUCCESS) + goto return_error; + strncpy(TaskTable[Handle].Name, Name, RESOURCE_NAMELEN); + TaskTable[Handle].Name[RESOURCE_NAMELEN-1] = 0; + TaskTable[Handle].TaskEntry = TaskEntry; + TaskTable[Handle].TaskCB.magic_nr = OS_NU_TASK_MAGIC; + TaskTable[Handle].TaskCB.handle = Handle; + *TaskHandle = Handle; + if (sem_sts == NU_SUCCESS) + NU_Release_Semaphore(&ProSemCB); + return(OS_OK); +} + +GLOBAL LONG +os_ChangePreemption(char preempt) +{ + if (NU_Change_Preemption(preempt) == NU_SUCCESS) + return(OS_OK); + else + return(OS_ERROR); +} diff -r c433cca731a3 -r 91e8dac34ada src/gpf2/osl/os_pro_ir.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gpf2/osl/os_pro_ir.c Fri Jun 22 05:56:16 2018 +0000 @@ -0,0 +1,105 @@ +/* + * This C module is a reconstruction based on the disassembly of + * os_pro.obj in frame_na7_db_ir.lib from the Leonardo package. + */ + +/* set of included headers from COFF symtab: */ +#include +#include +#include "gpfconf.h" /* FreeCalypso addition */ +#include "../../nucleus/nucleus.h" +#include "typedefs.h" +#include "os.h" +#include "gdi.h" +#include "os_types.h" +#include "os_glob.h" + +extern VOID *TCD_Current_Thread; +extern T_OS_TASK_TABLE_ENTRY TaskTable[]; +extern unsigned os_time_to_tick_multiplier; + +#define OS_NU_TASK_MAGIC 0xdeafbeef + +VOID +os_TaskEntry(UNSIGNED TaskHandle, VOID *argv) +{ + TaskTable[TaskHandle].TaskEntry(TaskHandle, 0); +} + +GLOBAL LONG +os_SuspendTask(OS_HANDLE Caller, ULONG Time) +{ + UNSIGNED SuspendTicks; + + SuspendTicks = TIME_TO_SYSTEM_TICKS(Time); + if (!SuspendTicks) + SuspendTicks = 1; + NU_Sleep(SuspendTicks); + return (OS_OK); +} + +GLOBAL LONG +os_ResumeTask(OS_HANDLE task_handle) +{ + if (NU_Resume_Task(&TaskTable[task_handle].TaskCB.TCB) == NU_SUCCESS) + return(OS_OK); + else + return(OS_ERROR); +} + +GLOBAL LONG +os_Relinquish(void) +{ + NU_Relinquish(); + return(OS_OK); +} + +GLOBAL OS_HANDLE +os_MyHandle(void) +{ + OS_NU_TASK *os_nu_task = (OS_NU_TASK *) TCD_Current_Thread; + + if (os_nu_task && os_nu_task->magic_nr == OS_NU_TASK_MAGIC) + return(os_nu_task->handle); + else + return(OS_NOTASK); +} + +GLOBAL LONG +os_GetTaskName(OS_HANDLE Caller, OS_HANDLE TaskHandle, char *Name) +{ + if (TaskHandle) { + if (TaskHandle > MaxTasks || !TaskTable[TaskHandle].Name[0]) + return(OS_ERROR); + strcpy(Name, TaskTable[TaskHandle].Name); + } else if (TCD_Current_Thread) { + NU_TASK *curtask = TCD_Current_Thread; + strcpy(Name, curtask->tc_name); + } else + strcpy(Name, "ROOT"); + return(OS_OK); +} + +GLOBAL LONG +os_DeferTask(OS_HANDLE task_handle, OS_TIME time) +{ + if (NU_Suspend_Task(&TaskTable[task_handle].TaskCB.TCB) == NU_SUCCESS) + return(OS_OK); + else + return(OS_ERROR); +} + +GLOBAL LONG +os_CheckTaskStack(OS_HANDLE Handle) +{ + register void *sp asm("sp"); + + if (*TaskTable[Handle].Stack != GUARD_PATTERN) + return(OS_ERROR); + if (TCD_Current_Thread) { + NU_TASK *curtask = TCD_Current_Thread; + if (sp < curtask->tc_stack_start) + return(OS_ERROR); + } + return(OS_OK); +} diff -r c433cca731a3 -r 91e8dac34ada src/gpf2/osl/os_sem_fl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gpf2/osl/os_sem_fl.c Fri Jun 22 05:56:16 2018 +0000 @@ -0,0 +1,206 @@ +/* + * This C module is a reconstruction based on the disassembly of + * os_sem.obj in frame_na7_db_fl.lib from the Leonardo package. + */ + +/* set of included headers from COFF symtab: */ +#include +#include +#include "gpfconf.h" /* FreeCalypso addition */ +#include "../../nucleus/nucleus.h" +#include "typedefs.h" +#include "os.h" +#include "gdi.h" +#include "os_types.h" +#include "os_glob.h" + +extern T_OS_SEM_TABLE_ENTRY SemTable[]; + +static NU_SEMAPHORE SemSemCB; + +static int +os_GetSemaphoreEntry(USHORT Index, OS_HANDLE *Handle) +{ + static USHORT Idx; + + if (Index == FIRST_ENTRY) + Idx = 0; + if (Index == FIRST_ENTRY || Index == NEXT_ENTRY) { + for (;;) { + Idx++; + if (Idx > MaxSemaphores) + return(OS_ERROR); + if (SemTable[Idx].Name[0]) + break; + } + } else + Idx = Index; + if (Idx > MaxSemaphores) + return(OS_ERROR); + if (SemTable[Idx].Name[0]) { + *Handle = Idx; + return(OS_OK); + } else + return(OS_ERROR); +} + +GLOBAL LONG +os_SemaphoreInformation(USHORT Index, char *Buffer) +{ + OS_HANDLE Handle; + OPTION SuspendType; + UNSIGNED Current, TasksWaiting; + NU_TASK *First; + CHAR Name[NU_MAX_NAME]; + + if (os_GetSemaphoreEntry(Index, &Handle) < 0) + return(OS_ERROR); + if (NU_Semaphore_Information(&SemTable[Handle].SemCB, Name, &Current, + &SuspendType, &TasksWaiting, &First) + != NU_SUCCESS) + return(OS_ERROR); + sprintf(Buffer, "Semname:%s Count:%ld Suspend:%d Waiting:%ld", Name, + Current, SuspendType, TasksWaiting); + return(OS_OK); +} + +GLOBAL LONG +os_SemInit(void) +{ + USHORT i; + + if (NU_Create_Semaphore(&SemSemCB, "SEMSEM", 1, NU_PRIORITY) + != NU_SUCCESS) + return(OS_ERROR); + for (i = 1; i <= MaxSemaphores; i++) + bzero(&SemTable[i], sizeof(T_OS_SEM_TABLE_ENTRY)); + return(OS_OK); +} + +GLOBAL LONG +os_ResetSemaphore(OS_HANDLE TaskHandle, OS_HANDLE SemHandle, + USHORT init_counter) +{ + STATUS sts; + + sts = NU_Obtain_Semaphore(&SemSemCB, NU_SUSPEND); + if (!SemTable[SemHandle].Name[0]) { +error_out: if (sts == NU_SUCCESS) + NU_Release_Semaphore(&SemSemCB); + return(OS_ERROR); + } + if (NU_Reset_Semaphore(&SemTable[SemHandle].SemCB, init_counter) + != NU_SUCCESS) + goto error_out; + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&SemSemCB); + return(OS_OK); +} + +GLOBAL LONG +os_QuerySemaphore(OS_HANDLE TaskHandle, OS_HANDLE SemHandle, USHORT *Count) +{ + OPTION SuspendType; + UNSIGNED SemCount, TasksWaiting; + NU_TASK *First; + CHAR Name[NU_MAX_NAME]; + + if (NU_Semaphore_Information(&SemTable[SemHandle].SemCB, Name, + &SemCount, &SuspendType, &TasksWaiting, + &First) != NU_SUCCESS) + return(OS_ERROR); + *Count = SemCount; + return(OS_OK); +} + +GLOBAL LONG +os_OpenSemaphore(OS_HANDLE TaskHandle, char *Name, OS_HANDLE *SemHandle) +{ + USHORT i; + + for (i = 1; i <= MaxSemaphores; i++) { + if (!SemTable[i].Name[0]) + continue; + if (strncmp(Name, SemTable[i].Name, RESOURCE_NAMELEN-1)) + continue; + *SemHandle = i; + return(OS_OK); + } + return(OS_ERROR); +} + +GLOBAL unsigned char * +os_FindSuspendingSema(unsigned int *tcb) +{ + USHORT i; + SM_SUSPEND *susp, *susp_loopchk; + + for (i = 1; i <= MaxSemaphores; i++) { + if (!SemTable[i].Name[0]) + continue; + susp = SemTable[i].SemCB.sm_suspension_list; + if (!susp) + continue; + if (susp->sm_suspended_task == (NU_TASK *)tcb) + return(SemTable[i].SemCB.sm_name); + susp = (SM_SUSPEND *)susp->sm_suspend_link.cs_next; + for (susp_loopchk = susp; susp != susp_loopchk; + susp = (SM_SUSPEND *)susp->sm_suspend_link.cs_next) + if (susp->sm_suspended_task == (NU_TASK *)tcb) + return(SemTable[i].SemCB.sm_name); + } + return(0); +} + +GLOBAL LONG +os_DestroySemaphore(OS_HANDLE TaskHandle, OS_HANDLE SemHandle) +{ + STATUS sts; + + sts = NU_Obtain_Semaphore(&SemSemCB, NU_SUSPEND); + if (!SemTable[SemHandle].Name[0]) { +error_out: if (sts == NU_SUCCESS) + NU_Release_Semaphore(&SemSemCB); + return(OS_ERROR); + } + if (NU_Delete_Semaphore(&SemTable[SemHandle].SemCB) != NU_SUCCESS) + goto error_out; + SemTable[SemHandle].Name[0] = 0; + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&SemSemCB); + return(OS_OK); +} + +GLOBAL LONG +os_CreateSemaphore(OS_HANDLE TaskHandle, char *Name, USHORT Count, + OS_HANDLE *SemHandle, OS_HANDLE MemPoolHandle) +{ + USHORT i; + STATUS sts; + + if (os_OpenSemaphore(TaskHandle, Name, SemHandle) == OS_OK) + return(OS_ERROR); + sts = NU_Obtain_Semaphore(&SemSemCB, NU_SUSPEND); + for (i = 1; i <= MaxSemaphores; i++) { + if (SemTable[i].Name[0]) + continue; + if (NU_Create_Semaphore(&SemTable[i].SemCB, Name, Count, + NU_PRIORITY) != NU_SUCCESS) + break; + strncpy(SemTable[i].Name, Name, RESOURCE_NAMELEN); + SemTable[i].Name[RESOURCE_NAMELEN-1] = 0; + *SemHandle = i; + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&SemSemCB); + return(OS_OK); + } + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&SemSemCB); + return(OS_ERROR); +} + +GLOBAL LONG +os_CloseSemaphore(OS_HANDLE TaskHandle, OS_HANDLE SemHandle) +{ + return(OS_OK); +} diff -r c433cca731a3 -r 91e8dac34ada src/gpf2/osl/os_sem_ir.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gpf2/osl/os_sem_ir.c Fri Jun 22 05:56:16 2018 +0000 @@ -0,0 +1,92 @@ +/* + * This C module is a reconstruction based on the disassembly of + * os_sem.obj in frame_na7_db_ir.lib from the Leonardo package. + */ + +/* set of included headers from COFF symtab: */ +#include +#include +#include "gpfconf.h" /* FreeCalypso addition */ +#include "../../nucleus/nucleus.h" +#include "typedefs.h" +#include "os.h" +#include "gdi.h" +#include "os_types.h" +#include "os_glob.h" + +extern T_OS_SEM_TABLE_ENTRY SemTable[]; +extern unsigned os_time_to_tick_multiplier; + +int +ReleaseSemaphoreCB(NU_SEMAPHORE *SemCB) +{ + if (NU_Release_Semaphore(SemCB) == NU_SUCCESS) + return(OS_OK); + else + return(OS_ERROR); +} + +GLOBAL LONG +os_ReleaseSemaphore(OS_HANDLE TaskHandle, OS_HANDLE SemHandle) +{ + if (NU_Release_Semaphore(&SemTable[SemHandle].SemCB) == NU_SUCCESS) + return(OS_OK); + else + return(OS_ERROR); +} + +int +ObtainSemaphoreCB(NU_SEMAPHORE *SemCB, ULONG Timeout, USHORT wait_check) +{ + UNSIGNED nu_timeout; + STATUS sts; + int ret; + + ret = OS_OK; + if (Timeout != OS_SUSPEND) + nu_timeout = TIME_TO_SYSTEM_TICKS(Timeout); + else if (wait_check == 1) + nu_timeout = 1; + else + nu_timeout = NU_SUSPEND; + for (;;) { + sts = NU_Obtain_Semaphore(SemCB, nu_timeout); + switch (sts) { + case NU_SUCCESS: + return(ret); + case NU_INVALID_SEMAPHORE: + return(OS_ERROR); + case NU_INVALID_SUSPEND: + nu_timeout = 0; + continue; + case NU_TIMEOUT: + case NU_UNAVAILABLE: + if (nu_timeout == 1 && wait_check == 1) { + nu_timeout = NU_SUSPEND; + ret = OS_WAITED; + continue; + } + return(OS_TIMEOUT); + default: + /* + * Disassembly reveals that the original code + * has an endless loop here, the equivalent + * of continue. My guess is that they simply + * forgot the default case, and so control + * falls onto the closing brace of the switch + * and then onto the closing brace of the for + * loop. But I prefer better error handling, + * hence the present addition. - Space Falcon + */ + return(OS_ERROR); + } + } +} + +GLOBAL LONG +os_ObtainSemaphore(OS_HANDLE TaskHandle, OS_HANDLE SemHandle, ULONG Timeout) +{ + if (SemHandle > MaxSemaphores) + return(OS_ERROR); + return ObtainSemaphoreCB(&SemTable[SemHandle].SemCB, Timeout, 0); +} diff -r c433cca731a3 -r 91e8dac34ada src/gpf2/osl/os_tim_fl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gpf2/osl/os_tim_fl.c Fri Jun 22 05:56:16 2018 +0000 @@ -0,0 +1,181 @@ +/* + * 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 +#include "gpfconf.h" /* FreeCalypso addition */ +#include "../../nucleus/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; + +#define BARRIER asm volatile ("": : :"memory") + +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); + } +} diff -r c433cca731a3 -r 91e8dac34ada src/gpf2/osl/os_tim_ir.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gpf2/osl/os_tim_ir.c Fri Jun 22 05:56:16 2018 +0000 @@ -0,0 +1,317 @@ +/* + * This C module is a reconstruction based on the disassembly of + * os_tim.obj in frame_na7_db_ir.lib from the Leonardo package, + * subsequently reworked by Space Falcon. + * + * The original decompilation has been contributed by Das Signal. + */ + +/* set of included headers from COFF symtab: */ +#include +#include "gpfconf.h" /* FreeCalypso addition */ +#include "../../nucleus/nucleus.h" +#include "typedefs.h" +#include "os.h" +#include "gdi.h" +#include "os_types.h" +#include "os_glob.h" + +extern T_OS_TIMER_ENTRY TimerTable[]; +extern T_OS_TIMER_TABLE_ENTRY *p_list[]; + +extern unsigned os_time_to_tick_multiplier; +extern unsigned os_tick_to_time_multiplier; + +extern unsigned volatile t_start_ticks; +extern T_OS_TIMER_TABLE_ENTRY *t_running; +extern int used_timers; +extern int next_t_handle; +extern int volatile t_list_access; +extern int max_used_timers; +extern NU_SEMAPHORE TimSemCB; +extern NU_TIMER os_timer_cb; + +#define BARRIER asm volatile ("": : :"memory") + +void +timer_error(int err) +{ +} + +/* forward declaration */ +void os_Timeout(UNSIGNED t_handle); + +static int +os_remove_timer_from_list(T_OS_TIMER_TABLE_ENTRY *timer) +{ + OS_TICK c_ticks; + + if (timer != t_running) { + if (timer->next != t_running) + timer->next->r_ticks += timer->r_ticks; + } else { + c_ticks = NU_Retrieve_Clock(); + if (timer->next == timer) { + t_running = 0; + } else { + timer->next->r_ticks = + t_start_ticks + timer->r_ticks + + timer->next->r_ticks - c_ticks; + t_running = timer->next; + } + NU_Control_Timer(&os_timer_cb, NU_DISABLE_TIMER); + if (t_running != NULL) { + t_start_ticks = c_ticks; + if (t_running->r_ticks != 0) + NU_Reset_Timer(&os_timer_cb, os_Timeout, + t_running->r_ticks, 0, + NU_ENABLE_TIMER); + } + } + if (timer->next != timer) { + timer->prev->next = timer->next; + timer->next->prev = timer->prev; + } + timer->next = NULL; + timer->prev = NULL; + timer->status = TMR_USED; + return TMR_USED; +} + +static unsigned +os_add_timer_to_list(T_OS_TIMER_TABLE_ENTRY *timer, OS_TICK ticks) +{ + T_OS_TIMER_TABLE_ENTRY *t_list; + OS_TICK c_ticks, e_ticks, r1_ticks, return_ticks; + + if (ticks == 0) + ticks = 1; + + c_ticks = NU_Retrieve_Clock(); + t_list = t_running; + if (t_list != NULL) { + e_ticks = c_ticks - t_start_ticks; + if (t_list->r_ticks >= e_ticks) { + r1_ticks = t_list->r_ticks - e_ticks; + t_list->r_ticks = r1_ticks; + } else { + r1_ticks = 0; + t_list->r_ticks = 0; + } + t_start_ticks = c_ticks; + return_ticks = 0; + while (ticks >= r1_ticks) { + ticks -= r1_ticks; + t_list = t_list->next; + if (t_list == t_running) + goto out; + r1_ticks = t_list->r_ticks; + } + t_list->r_ticks -= ticks; + if (t_list == t_running) { + t_running = timer; + t_start_ticks = c_ticks; + NU_Control_Timer(&os_timer_cb, NU_DISABLE_TIMER); + return_ticks = ticks; + } +out: + timer->next = t_list; + timer->prev = t_list->prev; + t_list->prev->next = timer; + t_list->prev = timer; + timer->r_ticks = ticks; + } else { + timer->next = timer; + timer->prev = timer; + timer->r_ticks = ticks; + t_start_ticks = c_ticks; + t_running = timer; + return_ticks = ticks; + } + timer->status = TMR_ACTIVE; + return return_ticks; +} + +void +os_Timeout(UNSIGNED t_handle) /* argument is unused */ +{ + ULONG s_ticks; + OS_HANDLE task_handle, e_handle; + USHORT t_index; + int i, done; + T_OS_TIMER_TABLE_ENTRY **t_r4; + T_OS_TIMER_TABLE_ENTRY *timer; + void (*timeout_func) (OS_HANDLE, OS_HANDLE, USHORT); + + if (t_list_access) { + t_start_ticks++; + NU_Reset_Timer(&os_timer_cb, os_Timeout, 1, 0, + NU_ENABLE_TIMER); + return; + } + + timer = t_running; + if (timer) { + s_ticks = 0; + done = 0; + i = 0; + do { + timeout_func = timer->TimeoutProc; + if (timer->p_ticks) + p_list[i++] = timer; + task_handle = timer->task_handle; + e_handle = timer->entity_handle; + t_index = timer->t_index; + timer->status = TMR_USED; + if (timer->next == timer) { + t_running = NULL; + done = 1; + } else { + timer->prev->next = timer->next; + timer->next->prev = timer->prev; + if (timer->next->r_ticks) { + t_running = timer->next; + s_ticks = timer->next->r_ticks; + done = 1; + } else + timer = timer->next; + } + timeout_func(task_handle, e_handle, t_index); + } + while (!done); + + if (s_ticks) { + t_start_ticks = NU_Retrieve_Clock(); + NU_Reset_Timer(&os_timer_cb, os_Timeout, s_ticks, 0, + NU_ENABLE_TIMER); + } + } + for (t_r4 = p_list; *t_r4; t_r4++) { + timer = *t_r4; + s_ticks = os_add_timer_to_list(timer, timer->p_ticks); + if (s_ticks) + NU_Reset_Timer(&os_timer_cb, os_Timeout, s_ticks, 0, + NU_ENABLE_TIMER); + *t_r4 = NULL; + } +} + +GLOBAL LONG os_StartTimer(OS_HANDLE TaskHandle, OS_HANDLE TimerHandle, + USHORT Index, OS_TIME InitialTime, + OS_TIME RescheduleTime) +{ + T_OS_TIMER_TABLE_ENTRY *timer; + OS_TICK ticks; + STATUS sts; + + if (TimerHandle > MaxSimultaneousTimer) + return(OS_ERROR); + timer = &TimerTable[TimerHandle].entry; + sts = NU_Obtain_Semaphore(&TimSemCB, NU_SUSPEND); + if (timer->status == TMR_FREE) { + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&TimSemCB); + return(OS_ERROR); + } + t_list_access = 1; + BARRIER; + if (timer->status == TMR_ACTIVE) + os_remove_timer_from_list(timer); + timer->t_handle = TimerHandle; + timer->task_handle = os_MyHandle(); + timer->entity_handle = TaskHandle; + timer->t_index = Index; + timer->p_ticks = TIME_TO_SYSTEM_TICKS(RescheduleTime); + ticks = os_add_timer_to_list(timer, TIME_TO_SYSTEM_TICKS(InitialTime)); + if (ticks) + NU_Reset_Timer(&os_timer_cb, os_Timeout, ticks, 0, + NU_ENABLE_TIMER); + BARRIER; + t_list_access = 0; + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&TimSemCB); + return OS_OK; +} + +GLOBAL LONG os_StopTimer(OS_HANDLE TaskHandle, OS_HANDLE TimerHandle) + /* TaskHandle argument is unused */ +{ + T_OS_TIMER_ENTRY *timer_e; + STATUS sts; + + if (TimerHandle > MaxSimultaneousTimer) + return(OS_ERROR); + timer_e = &TimerTable[TimerHandle]; + sts = NU_Obtain_Semaphore(&TimSemCB, NU_SUSPEND); + if (timer_e->entry.status == TMR_FREE) { + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&TimSemCB); + return OS_ERROR; + } + t_list_access = 1; + BARRIER; + if (timer_e->entry.status == TMR_ACTIVE) + os_remove_timer_from_list(&timer_e->entry); + BARRIER; + t_list_access = 0; + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&TimSemCB); + return OS_OK; +} + +GLOBAL LONG os_IncrementTick(OS_TICK ticks) +{ + return OS_OK; +} + +GLOBAL LONG os_DestroyTimer(OS_HANDLE TaskHandle, OS_HANDLE TimerHandle) + /* TaskHandle argument is unused */ +{ + STATUS sts; + T_OS_TIMER_ENTRY *timer_e; + + if (TimerHandle > MaxSimultaneousTimer) + return(OS_ERROR); + sts = NU_Obtain_Semaphore(&TimSemCB, NU_SUSPEND); + timer_e = &TimerTable[TimerHandle]; + if (timer_e->entry.status != TMR_USED) { + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&TimSemCB); + return OS_ERROR; + } + timer_e->next_t_handle = next_t_handle; + next_t_handle = TimerHandle; + timer_e->entry.status = TMR_FREE; + used_timers--; + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&TimSemCB); + return OS_OK; +} + +GLOBAL LONG os_CreateTimer(OS_HANDLE TaskHandle, + void (*TimeoutProc) (OS_HANDLE, OS_HANDLE, USHORT), + OS_HANDLE *TimerHandle, OS_HANDLE MemPoolHandle) + /* TaskHandle and MemPoolHandle arguments are unused */ +{ + STATUS sts; + T_OS_TIMER_ENTRY *timer_e; + + sts = NU_Obtain_Semaphore(&TimSemCB, NU_SUSPEND); + if (next_t_handle == 0) { /* no free timers left */ + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&TimSemCB); + return OS_ERROR; + } + + timer_e = &TimerTable[next_t_handle]; + timer_e->entry.status = TMR_USED; + timer_e->entry.TimeoutProc = TimeoutProc; + *TimerHandle = next_t_handle; + next_t_handle = timer_e->next_t_handle; + used_timers++; + if (max_used_timers < used_timers) + max_used_timers = used_timers; + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&TimSemCB); + return OS_OK; +}