FreeCalypso > hg > fc-tourmaline
diff src/gpf/osl/os_com_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_com_fl.c Fri Oct 16 06:23:26 2020 +0000 @@ -0,0 +1,310 @@ +/* + * 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 <stdio.h> +#include <string.h> +#include "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((unsigned char *) + 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((unsigned char *) + 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((unsigned char *) + 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((unsigned char *) + 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++) + memset(&ComTable[i], 0, sizeof(T_OS_COM_TABLE_ENTRY)); + return(OS_OK); +} + +GLOBAL LONG +os_CloseQueue(OS_HANDLE TaskHandle, OS_HANDLE ComHandle) +{ + return(OS_OK); +}