changeset 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 c433cca731a3
children ff91db8c9eb8
files src/gpf2/osl/os_com_fl.c src/gpf2/osl/os_com_ir.c src/gpf2/osl/os_drv.c src/gpf2/osl/os_evt.c src/gpf2/osl/os_isr.c src/gpf2/osl/os_mem_fl.c src/gpf2/osl/os_mem_ir.c src/gpf2/osl/os_mis_fl.c src/gpf2/osl/os_mis_ir.c src/gpf2/osl/os_pro_fl.c src/gpf2/osl/os_pro_ir.c src/gpf2/osl/os_sem_fl.c src/gpf2/osl/os_sem_ir.c src/gpf2/osl/os_tim_fl.c src/gpf2/osl/os_tim_ir.c
diffstat 15 files changed, 2560 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /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 <stdio.h>
+#include <string.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"
+
+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);
+}
--- /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 <stdio.h>
+#include <string.h>
+#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);
+}
--- /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);
+}
--- /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 <stdio.h>
+#include <string.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"
+
+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);
+}
--- /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 <string.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"
+
+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);
+}
--- /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 <stdio.h>
+#include <string.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"
+
+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);
+}
--- /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 <stdio.h>
+#include <string.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"
+
+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);
+	}
+}
--- /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 <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#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);
+}
--- /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);
+}
--- /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 <stdio.h>
+#include <string.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"
+
+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);
+}
--- /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 <stdio.h>
+#include <string.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"
+
+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);
+}
--- /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 <stdio.h>
+#include <string.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"
+
+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);
+}
--- /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 <stdio.h>
+#include <string.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"
+
+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);
+}
--- /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 <stdio.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"
+
+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);
+	}
+}
--- /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 <stdio.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"
+
+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;
+}