changeset 138:85994b210f6a

nuc-fw cleanup: old Nucleus demo (w/o TI fw framework) moved out of the way
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Mon, 11 Nov 2013 10:17:08 +0000
parents 5fe5559003b7
children 771d9fda7630
files nuc-fw/Makefile nuc-fw/cfgmagic/processconf.sh nuc-fw/nucdemo/Makefile nuc-fw/nucdemo/demo.c nuc-fw/nucleus/Makefile nuc-fw/nucleus/calirq.h nuc-fw/nucleus/caltimer.h nuc-fw/nucleus/debug-chases/README nuc-fw/nucleus/debug-chases/tct.S.dbg nuc-fw/nucleus/debug-chases/tms.c.dbg nuc-fw/nucleus/debug-chases/tmse.c.dbg nuc-fw/nucleus/demo/calirq.h nuc-fw/nucleus/demo/caltimer.h nuc-fw/nucleus/demo/demo.c nuc-fw/nucleus/demo/irqshell.S nuc-fw/nucleus/demo/nucdemo.Makefile nuc-fw/nucleus/demo/sdc.c nuc-fw/nucleus/demo/tmcal.c nuc-fw/nucleus/irqshell.S nuc-fw/nucleus/sdc.c nuc-fw/nucleus/tmcal.c
diffstat 21 files changed, 6410 insertions(+), 2342 deletions(-) [+]
line wrap: on
line diff
--- a/nuc-fw/Makefile	Mon Nov 11 09:56:23 2013 +0000
+++ b/nuc-fw/Makefile	Mon Nov 11 10:17:08 2013 +0000
@@ -1,4 +1,4 @@
-SUBDIR=	bsp finlink include nucdemo nucleus riviera serial sprintf sysglue
+SUBDIR=	bsp finlink include nucleus riviera serial sprintf sysglue
 
 default:	config.stamp
 	${MAKE} ${MFLAGS} -f Makefile.build $@
--- a/nuc-fw/cfgmagic/processconf.sh	Mon Nov 11 09:56:23 2013 +0000
+++ b/nuc-fw/cfgmagic/processconf.sh	Mon Nov 11 10:17:08 2013 +0000
@@ -46,9 +46,9 @@
 
 # Once we get some actual functionality, the following definitions
 # will likely depend on the target and feature configuration,
-# but for now all we have is a FreeNucleus RTOS demo.
+# but for now all we have is a Riviera skeleton.
 
-BUILD_COMPONENTS="bsp nucdemo nucleus riviera serial sprintf sysglue"
+BUILD_COMPONENTS="bsp nucleus riviera serial sprintf sysglue"
 export_to_mk BUILD_COMPONENTS
 
 BUILD_DEFAULT_IMAGE=ramImage
--- a/nuc-fw/nucdemo/Makefile	Mon Nov 11 09:56:23 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-CC=	arm-elf-gcc
-CFLAGS=	-O2 -fno-builtin -mthumb-interwork -mthumb
-CPPFLAGS=-I../nucleus
-
-OBJS=	demo.o
-
-all:	${OBJS}
-
-clean:
-	rm -f *.[oa] *errs
--- a/nuc-fw/nucdemo/demo.c	Mon Nov 11 09:56:23 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,530 +0,0 @@
-/* Include Nucleus C-Library file */
-//#include "ncl\inc\nu_ncl.h"
-
-/* Include necessary Nucleus PLUS files.  */
-#include "nucleus.h"
-
-/* Define serial output/input functionality. To disable serial I/O,
-   replace NU_TRUE with NU_FALSE */
-
-#define NU_SERIAL_OUTPUT  NU_TRUE
-#define NU_SERIAL_INPUT   NU_TRUE
-
-#if (NU_SERIAL_OUTPUT)
-#include "nu_sd.h"            /* Nucleus Serial Driver interface */
-#endif
-
-/* Define Application data structures.  */
-
-NU_TASK         Task_0;
-NU_TASK         Task_1;
-NU_TASK         Task_2;
-NU_TASK         Task_3;
-NU_TASK         Task_4;
-NU_TASK         Task_5;
-NU_QUEUE        Queue_0;
-NU_SEMAPHORE    Semaphore_0;
-NU_EVENT_GROUP  Event_Group_0;
-NU_MEMORY_POOL  System_Memory;
-
-
-/* Allocate global counters. */
-UNSIGNED  Task_Time;
-UNSIGNED  Task_2_messages_received;
-UNSIGNED  Task_2_invalid_messages;
-UNSIGNED  Task_1_messages_sent;
-NU_TASK  *Who_has_the_resource;
-UNSIGNED  Event_Detections;
-
-#if (NU_SERIAL_OUTPUT)
-NU_SERIAL_PORT  port;
-#endif
-
-#ifdef NU_FIQ_DEMO
-UINT32 FIQ_Count;
-#endif
-
-extern  UNSIGNED TMD_System_Clock;
-
-/* Define prototypes for function references.  */
-VOID    task_0(UNSIGNED argc, VOID *argv);
-VOID    task_1(UNSIGNED argc, VOID *argv);
-VOID    task_2(UNSIGNED argc, VOID *argv);
-VOID    task_3_and_4(UNSIGNED argc, VOID *argv);
-VOID    task_5(UNSIGNED argc, VOID *argv);
-CHAR    buffer[12]; /* temp buffer for Itoa conversion */
-INT     n; /* strlen */
-
-
-
-/* Define the Application_Initialize routine that determines the initial
-   Nucleus PLUS application environment.  */
-
-void    Application_Initialize(void *first_available_memory)
-{
-
-VOID           *pointer;
-STATUS         status;
-
-    /* Create a system memory pool that will be used to allocate task stacks,
-       queue areas, etc.  */
-    status = NU_Create_Memory_Pool(&System_Memory, "SYSMEM",
-                        first_available_memory, 25000, 50, NU_FIFO);
-    if (status != NU_SUCCESS)
-    {
-        ERC_System_Error(status);
-    }
-
-    /* Create each task in the system.  */
-
-    /* Create task 0.  */
-    NU_Allocate_Memory(&System_Memory, &pointer, 2000, NU_NO_SUSPEND);
-    status = NU_Create_Task(&Task_0, "TASK 0", task_0, 0, NU_NULL, pointer, 2000, 1, 20,
-                                                      NU_PREEMPT, NU_START);
-    if (status != NU_SUCCESS)
-    {
-        ERC_System_Error(status);
-    }
-
-    /* Create task 1.  */
-    NU_Allocate_Memory(&System_Memory, &pointer, 2000, NU_NO_SUSPEND);
-    status = NU_Create_Task(&Task_1, "TASK 1", task_1, 0, NU_NULL, pointer, 2000, 10, 5,
-                                                      NU_PREEMPT, NU_START);
-    if (status != NU_SUCCESS)
-    {
-        ERC_System_Error(status);
-    }
-
-    /* Create task 2.  */
-    NU_Allocate_Memory(&System_Memory, &pointer, 2000, NU_NO_SUSPEND);
-    status = NU_Create_Task(&Task_2, "TASK 2", task_2, 0, NU_NULL, pointer, 2000, 10, 5,
-                                                      NU_PREEMPT, NU_START);
-    if (status != NU_SUCCESS)
-    {
-        ERC_System_Error(status);
-    }
-
-    /* Create task 3.  Note that task 4 uses the same instruction area.  */
-    NU_Allocate_Memory(&System_Memory, &pointer, 2000, NU_NO_SUSPEND);
-    status = NU_Create_Task(&Task_3, "TASK 3", task_3_and_4, 0, NU_NULL, pointer,
-                                        2000, 5, 0, NU_PREEMPT, NU_START);
-    if (status != NU_SUCCESS)
-    {
-        ERC_System_Error(status);
-    }
-
-    /* Create task 4.  Note that task 3 uses the same instruction area.  */
-    NU_Allocate_Memory(&System_Memory, &pointer, 2000, NU_NO_SUSPEND);
-    status = NU_Create_Task(&Task_4, "TASK 4", task_3_and_4, 0, NU_NULL, pointer,
-                                        2000, 5, 0, NU_PREEMPT, NU_START);
-    if (status != NU_SUCCESS)
-    {
-        ERC_System_Error(status);
-    }
-
-    /* Create task 5.  */
-    NU_Allocate_Memory(&System_Memory, &pointer, 2000, NU_NO_SUSPEND);
-    status = NU_Create_Task(&Task_5, "TASK 5", task_5, 0, NU_NULL, pointer, 2000, 7, 0,
-                                                      NU_PREEMPT, NU_START);
-    if (status != NU_SUCCESS)
-    {
-        ERC_System_Error(status);
-    }
-
-
-    /* Create communication queue.  */
-    NU_Allocate_Memory(&System_Memory, &pointer, 100*sizeof(UNSIGNED),
-                                                        NU_NO_SUSPEND);
-    status = NU_Create_Queue(&Queue_0, "QUEUE 0", pointer, 100, NU_FIXED_SIZE, 1,
-                                                                      NU_FIFO);
-    if (status != NU_SUCCESS)
-    {
-        ERC_System_Error(status);
-    }
-
-    /* Create synchronization semaphore.  */
-    status = NU_Create_Semaphore(&Semaphore_0, "SEM 0", 1, NU_FIFO);
-    if (status != NU_SUCCESS)
-    {
-        ERC_System_Error(status);
-    }
-
-    /* Create event flag group.  */
-    status = NU_Create_Event_Group(&Event_Group_0, "EVGROUP0");
-    if (status != NU_SUCCESS)
-    {
-        ERC_System_Error(status);
-    }
-
-
-}
-
-/* Define the system timer task.  More complicated systems might use a
-   routine like this to perform periodic message sending and other time
-   oriented functions.  */
-
-
-void   task_0(UNSIGNED argc, VOID *argv)
-{
-
-STATUS          status;
-
-
-#if (NU_SERIAL_OUTPUT)
-CHAR            msg[40];
-INT             i;
-
-CHAR            ch;
-#endif /* NU_SERIAL_OUTPUT */
-
-
-#if (NU_SERIAL_OUTPUT)
-    /* Init the serial port. */
-    port.com_port   = DEFAULT_UART_PORT;
-    port.baud_rate  = DEFAULT_UART_BAUD;
-    port.data_bits  = DEFAULT_UART_DATA;
-    port.stop_bits  = DEFAULT_UART_STOP;
-    port.parity     = DEFAULT_UART_PARITY;
-    port.data_mode  = DEFAULT_UART_MODE;
-    port.communication_mode = SERIAL_MODE;
-    port.sd_buffer_size   =   DEFAULT_UART_BUFFER;
-
-    status = NU_SD_Init_Port (&port);
-    if (status != NU_SUCCESS)
-    {
-        ERC_System_Error(status);
-    }
-
-#endif /* NU_SERIAL_OUTPUT */
-
-
-    /* Access argc and argv just to avoid compilation warnings.  */
-    status =  (STATUS) argc + (STATUS) argv;
-
-    /* Set the clock to 0.  This clock ticks every 18 system timer ticks. */
-    Task_Time =  0;
-
-        while(1)
-        {
-
-            /* Sleep for 100 timer ticks.  The value of the tick is programmable
-               in INT.S and is relative to the speed of the target system.  */
-            NU_Sleep(100);
-
-#if (NU_SERIAL_OUTPUT)
-            NU_SD_Put_String("\n\r****************************************", &port);
-            NU_SD_Put_String("***************************************\n\r", &port);
-            NU_SD_Put_String(NU_Release_Information(), &port);
-            NU_SD_Put_String("\n\r", &port);
-
-            NU_SD_Put_String("****************************************", &port);
-            NU_SD_Put_String("***************************************\n\n\r", &port);
-            NU_SD_Put_String("System Variable Status: \n\n\r", &port);
-
-            strcpy(msg, "Task 0 time:                      ");
-	    sprintf(buffer, "%lu", Task_Time);
-            n = strlen(buffer);
-            if (n>=8)
-            {
-                strcat(msg, buffer);
-                strcat(msg, "\n\r");
-            }
-            else
-            {
-                for (i=0;i<(8-n);i++)
-                    strcat(msg, " ");
-                strcat(msg, buffer);
-                strcat(msg, "\n\r");
-            }
-
-            NU_SD_Put_String(msg, &port);
-
-            strcpy(msg, "Event detections:                 ");
-	    sprintf(buffer, "%lu", Event_Detections);
-            n = strlen(buffer);
-            if (n>=8)
-            {
-                strcat(msg, buffer);
-                strcat(msg, "\n\n\n\r");
-            }
-            else
-            {
-                for (i=0;i<(8-n);i++)
-                    strcat(msg, " ");
-                strcat(msg, buffer);
-                strcat(msg, "\n\n\n\r");
-            }
-
-            NU_SD_Put_String(msg, &port);
-
-            strcpy(msg, "Task 1 messages sent:             ");
-	    sprintf(buffer, "%lu", Task_1_messages_sent);
-            n = strlen(buffer);
-            if (n>=8)
-            {
-                strcat(msg, buffer);
-                strcat(msg, "\n\r");
-            }
-            else
-            {
-                for (i=0;i<(8-n);i++)
-                    strcat(msg, " ");
-                strcat(msg, buffer);
-                strcat(msg, "\n\r");
-            }
-
-            NU_SD_Put_String(msg, &port);
-
-            strcpy(msg, "Task 2 messages received:         ");
-	    sprintf(buffer, "%lu", Task_2_messages_received);
-            n = strlen(buffer);
-            if (n>=8)
-            {
-                strcat(msg, buffer);
-                strcat(msg, "\n\n\r");
-            }
-            else
-            {
-                for (i=0;i<(8-n);i++)
-                    strcat(msg, " ");
-                strcat(msg, buffer);
-                strcat(msg, "\n\n\r");
-            }
-
-            NU_SD_Put_String(msg, &port);
-
-            strcpy(msg, "Task 2 invalid messages:          ");
-	    sprintf(buffer, "%lu", Task_2_invalid_messages);
-            n = strlen(buffer);
-            if (n>=8)
-            {
-                strcat(msg, buffer);
-                strcat(msg, "\n\n\r");
-            }
-            else
-            {
-                for (i=0;i<(8-n);i++)
-                    strcat(msg, " ");
-                strcat(msg, buffer);
-                strcat(msg, "\n\n\r");
-            }
-
-            NU_SD_Put_String(msg, &port);
-
-            if (Who_has_the_resource == &Task_3)
-               NU_SD_Put_String("Who has the resource:               Task 3", &port);
-            else if (Who_has_the_resource == &Task_4)
-               NU_SD_Put_String("Who has the resource:               Task 4", &port);
-            else
-               NU_SD_Put_String("Who has the resource:               Nobody", &port);
-            NU_SD_Put_String("\n\n\n\r", &port);
-
-            strcpy(msg, "Timer Interrupts:                 ");
-	    sprintf(buffer, "%lu", TMD_System_Clock);
-            n = strlen(buffer);
-            if (n>=8)
-            {
-                strcat(msg, buffer);
-                strcat(msg, "\n\n\r");
-            }
-            else
-            {
-                for (i=0;i<(8-n);i++)
-                    strcat(msg, " ");
-                strcat(msg, buffer);
-                strcat(msg, "\n\n\r");
-            }
-
-            NU_SD_Put_String(msg, &port);
-
-            NU_SD_Put_String("Buffer:  ", &port);
-
-#if (NU_SERIAL_INPUT)
-            while (NU_SD_Data_Ready(&port))
-            {
-                ch = NU_SD_Get_Char(&port);
-                NU_SD_Put_Char(ch, &port);
-            }
-#endif /* NU_SERIAL_INPUT */
-
-
-            NU_SD_Put_String("\n\n\r", &port);
-
-
-#endif /* NU_SERIAL_OUTPUT */
-            /* Increment the time.  */
-            Task_Time++;
-
-            /* Set an event flag to lift the suspension on task 5.  */
-            status =  NU_Set_Events(&Event_Group_0, 1, NU_OR);
-
-        }
-
-}
-
-
-/* Define the queue sending task.  Note that the only things that cause
-   this task to suspend are queue full conditions and the time slice
-   specified in the configuration file.  */
-
-void   task_1(UNSIGNED argc, VOID *argv)
-{
-
-STATUS         status;
-UNSIGNED       Send_Message;
-
-    /* Access argc and argv just to avoid compilation warnings.  */
-    status =  (STATUS) argc + (STATUS) argv;
-
-    /* Initialize the message counter.  */
-    Task_1_messages_sent =  0;
-
-    /* Initialize the message contents.  The receiver will examine the
-       message contents for errors.  */
-    Send_Message = 0;
-
-    while(1)
-    {
-    
-         /* Send the message to Queue_0, which task 2 reads from.  Note
-            that if the destination queue fills up this task suspends until
-            room becomes available.  */
-         status =  NU_Send_To_Queue(&Queue_0, &Send_Message, 1, NU_SUSPEND);
-         
-         /* Determine if the message was sent successfully.  */
-         if (status == NU_SUCCESS)
-             Task_1_messages_sent++;
-             
-         /* Modify the contents of the next message to send.  */
-         Send_Message++;
-    }
-}
-
-
-/* Define the queue receiving task.  Note that the only things that cause
-   this task to suspend are queue empty conditions and the time slice
-   specified in the configuration file.   */
-
-void   task_2(UNSIGNED argc, VOID *argv)
-{
-
-STATUS         status; 
-UNSIGNED       Receive_Message;
-UNSIGNED       received_size;
-UNSIGNED       message_expected;
-
-    /* Access argc and argv just to avoid compilation warnings.  */
-    status =  (STATUS) argc + (STATUS) argv;
-
-    /* Initialize the message counter.  */
-    Task_2_messages_received =  0;
-
-    /* Initialize the message error counter.  */
-    Task_2_invalid_messages =  0;
-
-    /* Initialize the message contents to expect.  */
-    message_expected =  0;
-    
-    while(1)
-    {
-    
-         /* Retrieve a message from Queue_0, which task 1 writes to.  Note
-            that if the source queue is empty this task suspends until
-            something becomes available.  */
-         status =  NU_Receive_From_Queue(&Queue_0, &Receive_Message, 1, 
-                                &received_size, NU_SUSPEND);
-         
-         /* Determine if the message was received successfully.  */
-         if (status == NU_SUCCESS)
-             Task_2_messages_received++;
-             
-         /* Check the contents of the message against what this task
-            is expecting.  */
-         if ((received_size != 1) ||
-             (Receive_Message != message_expected))
-             Task_2_invalid_messages++;
-         
-         /* Modify the expected contents of the next message.  */
-         message_expected++;
-    }
-}
-
-
-/* Tasks 3 and 4 want a single resource.  Once one of the tasks gets the
-   resource, it keeps it for 100 clock ticks before releasing it.  During
-   this time the other task suspends waiting for the resource.  Note that
-   both task 3 and 4 use the same instruction areas but have different 
-   stacks.  */
-   
-void  task_3_and_4(UNSIGNED argc, VOID *argv)
-{
-
-STATUS  status;
-
-    /* Access argc and argv just to avoid compilation warnings.  */
-    status =  (STATUS) argc + (STATUS) argv;
-
-    /* Loop to allocate and deallocate the resource.  */
-    while(1)
-    {
-    
-         /* Allocate the resource.  Suspend until it becomes available.  */
-         status =  NU_Obtain_Semaphore(&Semaphore_0, NU_SUSPEND);
-         
-         /* If the status is successful, show that this task owns the 
-            resource.  */
-         if (status ==  NU_SUCCESS)
-         {
-         
-             Who_has_the_resource =  NU_Current_Task_Pointer();
-             
-             /* Sleep for 100 ticks to cause the other task to suspend on 
-                the resource.  */
-             NU_Sleep(100);
-             
-             /* Release the semaphore.  */
-             NU_Release_Semaphore(&Semaphore_0);
-        }
-    }
-}
-
-
-/* Define the task that waits for the event to be set by task 0.  */
-
-void  task_5(UNSIGNED argc, VOID *argv)
-{
-
-STATUS          status;
-UNSIGNED        event_group;
-
-    /* Access argc and argv just to avoid compilation warnings.  */
-    status =  (STATUS) argc + (STATUS) argv;
-
-    /* Initialize the event detection counter.  */
-    Event_Detections =  0;
-
-    /* Continue this process forever.  */
-    while(1)
-    {
-        /* Wait for an event and consume it.  */
-        status =  NU_Retrieve_Events(&Event_Group_0, 1, NU_OR_CONSUME,
-                                     &event_group, NU_SUSPEND);
-
-        /* If the status is okay, increment the counter.  */
-        if (status == NU_SUCCESS)
-        {
-          Event_Detections++;
-
-        }
-    }
-}
-
-
-#ifdef NU_FIQ_DEMO
-void FIQ_LISR(VOID)
-{
-    FIQ_Count++;
-}
-#endif
-
-
--- a/nuc-fw/nucleus/Makefile	Mon Nov 11 09:56:23 2013 +0000
+++ b/nuc-fw/nucleus/Makefile	Mon Nov 11 10:17:08 2013 +0000
@@ -5,7 +5,7 @@
 RANLIB=	arm-elf-ranlib
 
 IOBJS=	csc.o erc.o pmc.o pmce.o pmd.o smc.o smce.o smd.o tcc.o tcce.o tcd.o \
-	tct.o tmc.o tmd.o tms.o tmse.o tmt.o #irqshell.o
+	tct.o tmc.o tmd.o tms.o tmse.o tmt.o
 
 XTOBJS=	dmc.o dmce.o dmd.o dmf.o dmi.o dms.o erd.o eri.o evc.o evce.o evd.o \
 	evf.o evi.o hic.o hid.o hii.o inc.o ioc.o ioce.o iod.o iof.o ioi.o \
@@ -13,7 +13,6 @@
 	pid.o pif.o pii.o pis.o pise.o pmf.o pmi.o quc.o quce.o qud.o quf.o \
 	qui.o qus.o quse.o rlc.o rld.o smf.o smi.o sms.o smse.o tcf.o tcfe.o \
 	tci.o tcs.o tcse.o tmf.o tmi.o
-#	sdc.o tmcal.o
 
 XOBJS=	${XTOBJS} init.o
 AOBJS=	${IOBJS} init.o
@@ -21,9 +20,8 @@
 HDRS=	asm_defs.h cs_defs.h cs_extr.h dm_defs.h dm_extr.h er_defs.h er_extr.h \
 	ev_defs.h ev_extr.h hi_defs.h hi_extr.h in_defs.h in_extr.h io_defs.h \
 	io_extr.h mb_defs.h mb_extr.h nu_sd.h nucleus.h pi_defs.h pi_extr.h \
-	pm_defs.h pm_extr.h profiler.h qu_defs.h qu_extr.h sd_defs.h sd_extr.h \
-	sm_defs.h sm_extr.h tc_defs.h tc_extr.h tm_defs.h tm_extr.h \
-	calirq.h caltimer.h
+	pm_defs.h pm_extr.h profiler.h qu_defs.h qu_extr.h sm_defs.h sm_extr.h \
+	tc_defs.h tc_extr.h tm_defs.h tm_extr.h
 
 all:	libplus.iram.a libplus.xip.a
 
--- a/nuc-fw/nucleus/calirq.h	Mon Nov 11 09:56:23 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * Definitions for Calypso IRQ numbers and the related registers
- * Added to the FreeNucleus Calypso port by Spacefalcon the Outlaw.
- *
- * This header is usable from both .c and .S source files.
- */
-
-#ifndef _CALYPSO_IRQ_H
-#define _CALYPSO_IRQ_H
-
-#define	IRQ_WATCHDOG		0
-#define	IRQ_TIMER1		1
-#define	IRQ_TIMER2		2
-#define	IRQ_TSP_RX		3
-#define	IRQ_TPU_FRAME		4
-#define	IRQ_TPU_PAGE		5
-#define	IRQ_SIMCARD		6
-#define	IRQ_UART_MODEM		7
-#define	IRQ_KEYPAD_GPIO		8
-#define	IRQ_RTC_TIMER		9
-#define	IRQ_RTC_ALARM_I2C	10
-#define	IRQ_ULPD_GAUGING	11
-#define	IRQ_EXTERNAL		12
-#define	IRQ_SPI			13
-#define	IRQ_DMA			14
-#define	IRQ_API			15
-#define	IRQ_SIM_DETECT		16
-#define	IRQ_EXTERNAL_FIQ	17
-#define	IRQ_UART_IRDA		18
-#define	IRQ_ULPD_GSM_TIMER	19
-#define	IRQ_GEA			20
-
-#define	MAX_IRQ_NUM		20
-
-#define	INTH_BASE_ADDR		0xFFFFFA00
-
-#ifdef __ASSEMBLER__
-
-/*
- * Assembly source with cpp
- *
- * The most convenient way to access registers like these from ARM
- * assembly is to load the base address of the register block in some
- * ARM register, using only one ldr rN, =xxx instruction and only one
- * literal pool entry, and then access various registers in the block
- * from the same base using the immediate offset addressing mode.
- *
- * Here we define the offsets for the usage scenario above.
- */
-
-#define	IT_REG1		0x00
-#define	IT_REG2		0x02
-#define	MASK_IT_REG1	0x08
-#define	MASK_IT_REG2	0x0A
-#define	IRQ_NUM		0x10
-#define	FIQ_NUM		0x12
-#define	IRQ_CTRL	0x14
-#define	ILR_OFFSET	0x20
-
-#else
-
-/*
- * C source
- *
- * For access from C, we define the layout of the INTH register block
- * as a struct, and then define a pleudo-global-var for easy "volatile"
- * access.
- */
-
-struct inth_regs {
-	unsigned short	it_reg1;
-	unsigned short	it_reg2;
-	unsigned short	pad1[2];
-	unsigned short	mask_it_reg1;
-	unsigned short	mask_it_reg2;
-	unsigned short	pad2[2];
-	unsigned short	irq_num;
-	unsigned short	fiq_num;
-	unsigned short	irq_ctrl;
-	unsigned short	pad3[5];
-	unsigned short	ilr_irq[MAX_IRQ_NUM+1];
-};
-
-#define	INTH_REGS	(*(volatile struct inth_regs *) INTH_BASE_ADDR)
-
-/*
- * C code can now access INTH registers like this:
- *
- * old_mask = INTH_REGS.mask_it_reg1;
- * INTH_REGS.mask_it_reg1 = new_mask;
- */
-
-#endif
-
-#endif /* _CALYPSO_IRQ_H */
--- a/nuc-fw/nucleus/caltimer.h	Mon Nov 11 09:56:23 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Definitions for Calypso general-purpose timer registers
- * Added to the FreeNucleus Calypso port by Spacefalcon the Outlaw.
- *
- * This header is usable from both .c and .S source files.
- */
-
-#ifndef _CALYPSO_TIMER_H
-#define _CALYPSO_TIMER_H
-
-#define	TIMER1_BASE_ADDR	0xFFFE3800
-#define	TIMER2_BASE_ADDR	0xFFFE6800
-
-#ifdef __ASSEMBLER__
-
-/*
- * Assembly source with cpp
- *
- * The most convenient way to access registers like these from ARM
- * assembly is to load the base address of the register block in some
- * ARM register, using only one ldr rN, =xxx instruction and only one
- * literal pool entry, and then access various registers in the block
- * from the same base using the immediate offset addressing mode.
- *
- * Here we define the offsets for the usage scenario above.
- */
-
-#define	CNTL_TIM	0x00
-#define	LOAD_TIM	0x02
-#define	READ_TIM	0x04
-
-#else
-
-/*
- * C source
- *
- * For access from C, we define the layout of each timer register block
- * as a struct, and then define a pleudo-global-var for easy "volatile"
- * access to each of the 2 timers.
- */
-
-struct timer_regs {
-	unsigned char	cntl;
-	unsigned char	pad;
-	unsigned short	load;
-	unsigned short	read;
-};
-
-#define	TIMER1_REGS	(*(volatile struct timer_regs *) TIMER1_BASE_ADDR)
-#define	TIMER2_REGS	(*(volatile struct timer_regs *) TIMER2_BASE_ADDR)
-
-#endif
-
-/* CNTL register bit definitions */
-#define	CNTL_START		0x01
-#define	CNTL_AUTO_RELOAD	0x02
-#define	CNTL_CLOCK_ENABLE	0x20
-
-#endif /* include guard */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nuc-fw/nucleus/debug-chases/README	Mon Nov 11 10:17:08 2013 +0000
@@ -0,0 +1,4 @@
+During some of my debug sessions (wild goose chases after difficult bugs)
+I hacked the bloody hell out of some Nucleus modules, trying to instrument
+them to catch the bugs I was after.  This directory is a stash-away place
+for such ugly hacks.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nuc-fw/nucleus/debug-chases/tct.S.dbg	Mon Nov 11 10:17:08 2013 +0000
@@ -0,0 +1,3002 @@
+/*
+ ************************************************************************
+ *                                                                       
+ *               Copyright Mentor Graphics Corporation 2002              
+ *                         All Rights Reserved.                          
+ *                                                                       
+ * THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS  
+ * THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS   
+ * SUBJECT TO LICENSE TERMS.                                             
+ *                                                                       
+ ************************************************************************
+ ************************************************************************
+ *                                                                       
+ * FILE NAME                              VERSION                        
+ *                                                                       
+ *      tct.s                   Nucleus PLUS\ARM925\Code Composer 1.14.1 
+ *                                                                       
+ * COMPONENT                                                             
+ *                                                                       
+ *      TC - Thread Control                                              
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This file contains the target processor dependent routines for   
+ *      performing target-dependent scheduling functions.                
+ *                                                                       
+ * FUNCTIONS                                                             
+ *                                                                       
+ *      TCT_Control_Interrupts              Enable / disable interrupts  
+ *                                          by changing                  
+ *                                          TCD_Interrupt_Level          
+ *      TCT_Local_Control_Interrupts        Enable/disable interrupts    
+ *                                          by not changing              
+ *                                          TCD_Interrupt_Level          
+ *      TCT_Restore_Interrupts              Restores interrupts to the   
+ *                                          level in TCD_Interrupt_Level 
+ *      TCT_Build_Task_Stack                Build initial task stack     
+ *      TCT_Build_HISR_Stack                Build initial HISR stack     
+ *      TCT_Build_Signal_Frame              Build signal handler frame   
+ *      TCT_Check_Stack                     Check current stack          
+ *      TCT_Schedule                        Schedule the next thread     
+ *      TCT_Control_To_Thread               Transfer control to a thread 
+ *      TCT_Control_To_System               Transfer control from thread 
+ *      TCT_Signal_Exit                     Exit from signal handler     
+ *      TCT_Current_Thread                  Returns a pointer to current 
+ *                                            thread                     
+ *      TCT_Set_Execute_Task                Sets TCD_Execute_Task under  
+ *                                            protection from interrupts 
+ *      TCT_Protect                         Protect critical section     
+ *      TCT_Unprotect                       Unprotect critical section   
+ *      TCT_Unprotect_Specific              Release specific protection  
+ *      TCT_Set_Current_Protect             Set the thread's current     
+ *                                            protection field           
+ *      TCT_Protect_Switch                  Switch to protected thread   
+ *      TCT_Schedule_Protected              Schedule the protected thread
+ *      TCT_Interrupt_Context_Save          Save interrupted context     
+ *      TCT_Interrupt_Context_Restore       Restore interrupted context  
+ *      TCT_Activate_HISR                   Activate a HISR              
+ *      TCT_HISR_Shell                      HISR execution shell         
+ *                                                                       
+ * DEPENDENCIES                                                          
+ *                                                                       
+ *      cs_extr.h                           Common Service functions     
+ *      tc_extr.h                           Thread Control functions     
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      B. Ronquillo     08-28-2002           Released version 1.14.1    
+ *                                                                       
+ ************************************************************************
+ */
+
+#define         NU_SOURCE_FILE
+
+/*
+ ******************************
+ * INCLUDE ASSEMBLY CONSTANTS *
+ ******************************
+ * Define constants used in low-level initialization. 
+ */
+
+#include "asm_defs.h"
+
+	.code 32
+
+/* TCT_System_Limit is a global variable defined in this module */
+
+	.comm	TCT_System_Limit,4,4
+
+    .text
+
+/*
+ **********************************
+ * LOCAL VARIABLE DECLARATIONS    *
+ **********************************
+ * Define pointers to system variables so their addresses may be obtained in a
+ * pc-relative manner. 
+ */
+
+System_Limit:
+        .word   TCT_System_Limit
+
+Int_Level:
+        .word   TCD_Interrupt_Level
+
+Task_Shell:
+        .word   TCC_Task_Shell
+
+HISR_Shell:
+        .word   TCT_HISR_Shell
+
+Signal_Shell:
+        .word   TCC_Signal_Shell
+
+Current_Thread:
+        .word   TCD_Current_Thread
+
+Execute_HISR:
+        .word   TCD_Execute_HISR
+
+Execute_Task:
+        .word   TCD_Execute_Task
+
+Time_Slice:
+        .word   TMD_Time_Slice
+
+Slice_State:
+        .word   TMD_Time_Slice_State
+
+System_Stack:
+        .word   TCD_System_Stack
+
+Int_Count:
+        .word   TCD_Interrupt_Count
+
+HISR_Tails:
+        .word   TCD_Active_HISR_Tails
+
+HISR_Heads:
+        .word   TCD_Active_HISR_Heads
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ * TCT_Control_Interrupts                                                
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function enables and disables interrupts as specified by    
+ *      the caller.  Interrupts disabled by this call are left disabled  
+ *      until the another call is made to enable them.                   
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      Application                                                      
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      new_level                           New interrupt enable level   
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      old_level                           Previous interrupt enable    
+ *                                            level                      
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *      C. Meredith     03-01-1994      Lockout interrupts while setting 
+ *                                        up the new level, resutling in 
+ *                                        version 1.1                    
+ *      D. Lamie        03-18-1994      Verified version 1.1             
+ *      M. Trippi       02-03-1997      Masked the return value to only  
+ *                                        return the interrupt bits.     
+ *                                        (SPR0252)                      
+ *                                                                       
+ ************************************************************************
+ */
+
+@INT TCT_Control_Interrupts (INT new_level)
+@{
+
+        .globl  TCT_Control_Interrupts
+TCT_Control_Interrupts:
+
+@INT     old_level;                          Old interrupt level      
+
+@    lock out all interrupts before any checking or changing
+
+@    Obtain the current interrupt lockout posture. 
+@    old_level =  TCD_Interrupt_Level;
+
+@    Setup new interrupt lockout posture. 
+@    TCD_Interrupt_Level =  new_level;
+
+@    renable interrupts for the specified lockout
+
+@    Return old interrupt lockout level. 
+@    return(old_level);
+
+        MRS     r2,CPSR                     @ Pickup current CPSR
+        ORR     r2,r2,#LOCKOUT              @ Build lockout CPSR
+        MSR     CPSR,r2                     @ Lockout interrupts temporarily
+        LDR     r1, Int_Level               @ Pickup interrupt level
+        LDR     r3,[r1, #0]                 @ Pickup current interrupt lockout
+        BIC     r2,r2,#LOCK_MSK             @ Clear lockout mask
+        ORR     r2,r2,r0                    @ Build new CPSR with appropriate
+                                            @   interrupts locked out
+        STR     r0,[r1,#0]                  @ Save current lockout 
+        MSR     CPSR,r2                     @ Setup new CPSR lockout bits
+        AND     r0,r3,#LOCK_MSK             @ Return previous lockout (SPR0252)
+      
+        BX      r14                         @ Return to caller
+
+@}    
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ * TCT_Local_Control_Interrupts                                          
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function enables and disables interrupts as specified by    
+ *      the caller.                                                      
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      Application                                                      
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      new_level                           New interrupt enable level   
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      old_level                           Previous interrupt enable    
+ *                                            level                      
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      C. Meredith     03-01-1994      Created initial version 1.1      
+ *      D. Lamie        03-18-1994      Verified version 1.1             
+ *      M. Trippi       02-03-1997      Masked the return value to only  
+ *                                        return the interrupt bits.     
+ *                                        (SPR0252)                      
+ *                                                                       
+ ************************************************************************
+ */
+
+@INT TCT_Local_Control_Interrupts (INT new_level)
+@{
+
+	.globl  TCT_Local_Control_Interrupts
+TCT_Local_Control_Interrupts:
+
+@INT     old_level;                          Old interrupt level      
+
+@    read in the old level
+@    old_level = current interrupt level of processor;
+
+        MRS     r2,CPSR                     @ Pickup current CPSR
+        MOV     r3,r2                       @ save the old level
+
+@    clear out the old level and set the new level
+@    current interrupt level of processor &= ~LOCKOUT;
+@    current interrupt level of processor |= new_level;
+
+        BIC     r2,r2,#LOCK_MSK             @ Clear all current interrupts
+        ORR     r2,r2,r0                    @ Build new CPSR with new
+                                            @ interrupt level
+        MSR     CPSR,r2                     @ Setup new CPSR interrupt bits
+
+@    Return old interrupt lockout level. 
+@    return(old_level);
+
+        AND     r0,r3,#LOCK_MSK             @ Return previous lockout (SPR0252)
+       
+        BX      r14                         @ Return to caller
+
+@}    
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *  TCT_Restore_Interrupts                                               
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function restores interrupts to that specified in the global
+ *      TCD_Interrupt_Level variable.                                    
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      Application                                                      
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      None.                                                            
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None.                                                            
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      C. Meredith     03-01-1994      Created initial version 1.1      
+ *      D. Lamie        03-18-1994      Verified version 1.1             
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID TCT_Restore_Interrupts  (VOID)
+@{
+
+	.globl  TCT_Restore_Interrupts
+TCT_Restore_Interrupts:
+
+@ Lock out all interrupts before any checking or changing
+@ Obtain the current interrupt lockout posture. 
+@ Reload the level base on the TCD_Interrupt_Level variable
+
+        MRS     r1,CPSR                     @ Pickup current CPSR
+        MOV     r2,r1                       @ save the CPSR value
+        ORR     r1,r1,#LOCKOUT              @ Build lockout CPSR
+        MSR     CPSR,r1                     @ Lockout interrupts temporarily
+        BIC     r2,r2,#LOCK_MSK             @ Clear current interrupt levels
+        LDR     r1,Int_Level                @ Load address of TCD_Interrupt_Level
+        LDR     r0,[r1, #0]                 @ Pickup current interrupt lockout
+        ORR     r2,r2,r0                    @ Build new CPSR with appropriate
+                                            @ interrupts locked out
+        MSR     CPSR,r2                     @ Setup new CPSR lockout bits
+
+        BX      r14                         @ Return to caller
+
+@}    
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_Build_Task_Stack                                             
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function builds an initial stack frame for a task.  The     
+ *      initial stack contains information concerning initial values of  
+ *      registers and the task's point of entry.  Furthermore, the       
+ *      initial stack frame is in the same form as an interrupt stack    
+ *      frame.                                                           
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      TCC_Create_Task                     Create a new task            
+ *      TCC_Reset_Task                      Reset the specified task     
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      task                                Task control block pointer   
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID  TCT_Build_Task_Stack(TC_TCB *task)
+@{
+
+	.globl  TCT_Build_Task_Stack
+TCT_Build_Task_Stack:
+
+    @ Pickup the stack base. 
+@    REG_Stack_Base =  (BYTE_PTR) task -> tc_stack_start;
+
+        LDR     r2,[r0,#0x24]               @ Pickup the stack starting address
+
+    @ Pickup the stack size. 
+@    REG_Stack_Size =  task -> tc_stack_size;
+
+        LDR     r1,[r0,#0x30]               @ Pickup the stack size in bytes
+
+    @ Calculate the stack ending address. 
+@    REG_Stack_End =  REG_Stack_Base + REG_Stack_Size - 1;
+
+        ADD     r3,r1,r2                    @ Compute the beginning of stack
+        BIC     r3,r3,#3                    @ Insure word alignment
+        SUB     r3,r3,#4                    @ Reserve a word
+
+    @ Save the stack ending address. 
+@    task -> tc_stack_end =  REG_Stack_End;
+
+        STR     r3,[r0,#0x28]               @ Save the stack ending address
+
+    @ Reference the task shell. 
+@    REG_Function_Ptr =  (VOID *) TCC_Task_Shell;
+
+@ Build an initial stack.  This initial stack frame facilitates an 
+@ interrupt return to the TCC_Task_Shell function, which in turn 
+@ invokes the application task.  The initial stack frame has the 
+@ following format:
+
+@               (Lower Address) Stack Top ->    1       (Interrupt stack type)
+@                                               CPSR    Saved CPSR
+@                                               r0      Saved r0
+@                                               r1      Saved r1
+@                                               r2      Saved r2
+@                                               r3      Saved r3
+@                                               r4      Saved r4
+@                                               r5      Saved r5
+@                                               r6      Saved r6
+@                                               r7      Saved r7
+@                                               r8      Saved r8
+@                                               r9/sb   Saved r9/sl
+@                                               r10/sl   Saved r10/sl
+@                                               fp      Saved fp
+@                                               r12      Saved r12
+@                                               r13      Saved r13
+@                                               r14      Saved r14
+@               (Higher Address) Stack Bottom-> r15      Saved r15
+  
+
+        LDR     r2, Task_Shell              @ Pickup address of shell entry
+        STR     r2,[r3], #-4                @ Store entry address on stack
+        MOV     r2,#0                       @ Clear value for initial registers
+        STR     r2,[r3], #-4                @ Store initial r14
+        ADD     r2,r3,#8                    @ Compute initial r13
+        STR     r2,[r3], #-4                @ Store initial r13 (Stack Bottom)
+        STR     r2,[r3], #-4                @ Store initial r12
+        STR     r2,[r3], #-4                @ Store initial fp
+        LDR     r2,[r0,#0x24]               @ Pickup the stack starting address
+        STR     r2,[r3], #-4                @ Store initial r10/sl
+        MOV     r2,#0                       @ Clear value for initial registers
+        STR     r2,[r3], #-4                @ Store initial r9/sb
+        STR     r2,[r3], #-4                @ Store initial r8
+        STR     r2,[r3], #-4                @ Store initial r7
+        STR     r2,[r3], #-4                @ Store initial r6
+        STR     r2,[r3], #-4                @ Store initial r5
+        STR     r2,[r3], #-4                @ Store initial r4
+        STR     r2,[r3], #-4                @ Store initial r3
+        STR     r2,[r3], #-4                @ Store initial r2
+        STR     r2,[r3], #-4                @ Store initial r1
+        STR     r2,[r3], #-4                @ Store initial r0
+        MSR     CPSR_f,r2                   @ Clear the flags
+        MRS     r2,CPSR                     @ Pickup the CPSR
+        BIC     r2,r2,#LOCK_MSK             @ Clear initial interrupt lockout
+        STR     r2,[r3], #-4                @ Store CPSR on the initial stack
+        MOV     r2,#1                       @ Build interrupt stack type (1)
+        STR     r2,[r3, #0]                 @ Store stack type on the top 
+
+    @ Save the minimum amount of remaining stack memory. 
+@    task -> tc_stack_minimum =  REG_Stack_Size - 72;
+
+        MOV     r2,#72                      @ Size of interrupt stack frame
+        SUB     r1,r1,r2                    @ Compute minimum available bytes
+        STR     r1,[r0, #0x34]              @ Save in minimum stack area
+
+    @ Save the new stack pointer into the task's control block. 
+@    task -> tc_stack_pointer =  (VOID *) Stack_Top;
+
+        STR     r3,[r0, #0x2C]              @ Save stack pointer
+
+        BX      r14                         @ Return to caller
+
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_Build_HISR_Stack                                             
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function builds an HISR stack frame that allows quick       
+ *      scheduling of the HISR.                                          
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      TCC_Create_HISR                     Create HISR function         
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      hisr                                HISR control block pointer   
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID  TCT_Build_HISR_Stack(TC_HCB *hisr)
+@{
+
+	.globl  TCT_Build_HISR_Stack
+TCT_Build_HISR_Stack:
+
+    @ Pickup the stack base. 
+@    REG_Stack_Base =  (BYTE_PTR) hisr -> tc_stack_start;
+
+        LDR     r2,[r0,#0x24]               @ Pickup the stack starting address
+
+    @ Pickup the stack size. 
+@    REG_Stack_Size =  hisr -> tc_stack_size;
+
+        LDR     r1,[r0,#0x30]               @ Pickup the stack size in bytes
+
+    @ Calculate the stack ending address. 
+@    REG_Stack_End =  REG_Stack_Base + REG_Stack_Size;
+
+        ADD     r3,r1,r2                    @ Compute the beginning of stack
+        BIC     r3,r3,#3                    @ Insure word alignment
+        SUB     r3,r3,#4                    @ Reserve a word
+
+    @ Save the stack ending address. 
+@    hisr -> tc_stack_end =  REG_Stack_End;
+
+        STR     r3,[r0,#0x28]               @ Save the stack ending address
+
+    @ Reference the HISR shell. 
+@    REG_Function_Ptr =  (VOID *) TCT_HISR_Shell;
+
+@ Build an initial stack.  This initial stack frame facilitates an 
+@ solicited return to the TCT_HISR_Shell function, which in turn 
+@ invokes the appropriate HISR.  The initial HISR stack frame has the 
+@ following format:
+
+@               (Lower Address) Stack Top ->    0       (Solicited stack type)
+@                !!FOR THUMB ONLY!!             0/0x20  Saved state mask
+@                                               r4      Saved r4
+@                                               r5      Saved r5
+@                                               r6      Saved r6
+@                                               r7      Saved r7
+@                                               r8      Saved r8
+@                                               r9/sb   Saved r9/sl
+@                                               r10/sl   Saved r10/sl
+@                                               fp      Saved fp
+@                                               r12      Saved r12
+@               (Higher Address) Stack Bottom-> r15      Saved r15
+   
+
+        LDR     r2,HISR_Shell               @ Pickup address of shell entry
+        STR     r2,[r3], #-4                @ Store entry address on stack
+        ADD     r2,r3,#4                    @ Compute initial r13
+        STR     r2,[r3], #-4                @ Store initial r12
+        STR     r2,[r3], #-4                @ Store initial fp
+        LDR     r2,[r0,#0x24]               @ Pickup the stack starting address
+        STR     r2,[r3], #-4                @ Store initial r10/sl
+        MOV     r2,#0                       @ Clear value for initial registers
+        STR     r2,[r3], #-4                @ Store initial r9/sb
+        STR     r2,[r3], #-4                @ Store initial r8
+        STR     r2,[r3], #-4                @ Store initial r7
+        STR     r2,[r3], #-4                @ Store initial r6
+        STR     r2,[r3], #-4                @ Store initial r5
+        STR     r2,[r3], #-4                @ Store initial r4
+#if 1	/* was .if THUMB */
+        STR     r2,[r3], #-4                @ Store initial state mask
+#endif
+        STR     r2,[r3, #0]                 @ Store solicited stack type on the
+                                            @ top of the stack 
+
+    @ Save the minimum amount of remaining stack memory. 
+@    hisr -> tc_stack_minimum =  REG_Stack_Size - (ARM)44 or (THUMB)48;
+
+#if 1	/* was .if THUMB */
+        MOV     r2,#48                      @ Size of solicited stack frame
+#else
+        MOV     r2,#44                      @ Size of solicited stack frame
+#endif
+
+        SUB     r1,r1,r2                    @ Compute minimum available bytes
+        STR     r1,[r0, #0x34]              @ Save in minimum stack area
+
+    @ Save the new stack pointer into the task's control block. 
+@    hisr -> tc_stack_pointer =  (VOID *) Stack_Top;
+
+        STR     r3,[r0, #0x2C]              @ Save stack pointer
+
+        BX      r14                         @ Return to caller
+
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_Build_Signal_Frame                                           
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function builds a frame on top of the task's stack to       
+ *      cause the task's signal handler to execute the next time         
+ *      the task is executed.                                            
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      TCC_Send_Signals                    Send signals to a task       
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      task                                Task control block pointer   
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID  TCT_Build_Signal_Frame(TC_TCB *task)
+@{
+
+	.globl  TCT_Build_Signal_Frame
+TCT_Build_Signal_Frame:
+
+    @ Pickup the stack pointer. 
+@    REG_Stack_Ptr =  (BYTE_PTR) task -> tc_stack_pointer;
+
+        LDR     r3,[r0,#0x2c]               @ Pickup the current stack pointer
+
+    @ Reference the Signal shell. 
+@    REG_Function_Ptr =  (VOID *) TCC_Signal_Shell;
+
+@ Build a signal stack.  This signal stack frame facilitates an 
+@ solicited return to the TCC_Signal_Shell function, which in turn 
+@ invokes the appropriate signal handler.  The initial HISR stack frame 
+@ has the following format:
+
+@               (Lower Address) Stack Top ->    0       (Solicited stack type)
+@                !!FOR THUMB ONLY!!             0/0x20  Saved state mask
+@                                               r4      Saved r4
+@                                               r5      Saved r5
+@                                               r6      Saved r6
+@                                               r7      Saved r7
+@                                               r8      Saved r8
+@                                               r9/sb   Saved r9/sl
+@                                               r10/sl   Saved r10/sl
+@                                               fp      Saved fp
+@                                               r12      Saved r12
+@               (Higher Address) Stack Bottom-> r15      Saved r15
+   
+
+        LDR     r2,Signal_Shell             @ Pickup address of shell entry
+        SUB     r3,r3,#4
+        STR     r2,[r3], #-4                @ Store entry address on stack
+        ADD     r2,r3,#4                    @ Compute initial r13
+        STR     r2,[r3], #-4                @ Store initial r12
+        STR     r2,[r3], #-4                @ Store initial fp
+        LDR     r2,[r0,#0x24]               @ Pickup the stack starting address
+        STR     r2,[r3], #-4                @ Store initial r10/sl
+        MOV     r2,#0                       @ Clear value for initial registers
+        STR     r2,[r3], #-4                @ Store initial r9/sb
+        STR     r2,[r3], #-4                @ Store initial r8
+        STR     r2,[r3], #-4                @ Store initial r7
+        STR     r2,[r3], #-4                @ Store initial r6
+        STR     r2,[r3], #-4                @ Store initial r5
+        STR     r2,[r3], #-4                @ Store initial r4
+#if 0
+        MOV     r1,#0x20                    @ Get initial state mask
+        STR     r1,[r3], #-4                @ Store initial state mask  
+#else
+	STR	r2,[r3], #-4		    @ TCC_Signal_Shell is an ARM proc
+#endif
+
+        STR     r2,[r3, #0]                 @ Store solicited stack type on the
+                                            @ top of the stack 
+
+    @ Save the new stack pointer into the task's control block. 
+@    task -> tc_stack_pointer =  (VOID *) (REG_Stack_Ptr - REG_Stack_Size);
+
+        STR     r3,[r0, #0x2C]              @ Save stack pointer
+
+        BX      r14                         @ Return to caller
+
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_Check_Stack                                                  
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function checks the current stack for overflow conditions.  
+ *      Additionally, this function keeps track of the minimum amount    
+ *      of stack space for the calling thread and returns the current    
+ *      available stack space.                                           
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      TCC_Send_Signals                    Send signals to a task       
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      ERC_System_Error                    System error handler         
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      available bytes in stack                                         
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *                                                                       
+ ************************************************************************
+ */
+
+@UNSIGNED  TCT_Check_Stack(void)
+@{
+
+	.globl  TCT_Check_Stack
+TCT_Check_Stack:
+
+@TC_TCB         *thread;
+@UNSIGNED       remaining;
+
+    @ Pickup the current task/HISR pointer. 
+@    thread =  (TC_TCB *) TCD_Current_Thread;
+
+        LDR     r0,Current_Thread           @ Pickup address of thread pointer
+        LDR     r0,[r0,#0]                  @ Pickup thread pointer
+
+    @ Determine if there is a current thread. 
+@    if (thread)
+@    {
+
+        CMP     r0,#0                       @ Determine if a thread is active
+        MOV     r3,#0                       @ Default remaining value
+        BEQ     TCT_Skip_Stack_Check        @ If NU_NULL, skip stack checking
+
+        @ Determine if the stack pointers are out of range. 
+@        if ((thread -> tc_stack_pointer < thread -> tc_stack_start) ||
+@            (thread -> tc_stack_pointer > thread -> tc_stack_end))
+
+        LDR     r2,[r0,#0x24]               @ Pickup start of stack area
+        CMP     r13,r2                      @ Compare with current stack ptr
+        BLT     TCT_Stack_Range_Error       @ If less, stack is out of range
+        LDR     r1,[r0,#0x28]               @ Pickup end of stack area
+        CMP     r13,r1                      @ Compare with current stack ptr
+        BLE     TCT_Stack_Range_Okay        @ If less, stack range is okay
+
+            @ Stack overflow condition exits. 
+@            ERC_System_Error(NU_STACK_OVERFLOW);
+
+TCT_Stack_Range_Error:
+
+        STR     r14,[r13, #4]!              @ Store r14 on the stack
+        MOV     r0,#3                       @ Build NU_STACK_OVERFLOW code
+        BL      ERC_System_Error            @ Call system error handler.  Note:
+                                            @ control is not returned!  
+                                            @ Examine stack to find return 
+                                            @ address of this routine.
+
+TCT_Stack_Range_Okay:
+
+    @ Calculate the amount of available space on the stack. 
+@    remaining =  (BYTE_PTR) thread -> tc_stack_pointer -
+@                        (BYTE_PTR) thread -> tc_stack_start;
+
+        SUB     r3,r13,r2                   @ Calculate remaining stack size
+
+    @ Determine if there is enough memory on the stack to save all of the
+    @ registers. 
+@    if (remaining < 80)
+
+        CMP     r3,#80                      @ Is there enough room for an 
+                                            @ interrupt frame?
+        BCS     TCT_No_Stack_Error          @ If so, no stack overflow yet
+
+            @ Stack overflow condition is about to happen. 
+@            ERC_System_Error(NU_STACK_OVERFLOW);
+
+        STR     r14,[r13, #4]!              @ Store r14 on the stack
+        MOV     r0,#3                       @ Build NU_STACK_OVERFLOW code
+        BL      ERC_System_Error            @ Call system error handler.  Note:
+                                            @ control is not returned!  
+                                            @ Examine stack to find return 
+                                            @ address of this routine.
+
+TCT_No_Stack_Error:
+
+    @ Determine if this is a new minimum amount of stack space. 
+@    if (remaining < thread -> tc_stack_minimum)
+
+        LDR     r2,[r0,#0x34]
+        CMP     r3,r2
+        STRCC   r3,[r0,#0x34]
+
+        @ Save the new stack minimum. 
+@       thread -> tc_stack_minimum =  remaining;
+@    }
+@    else
+
+        @ Set the remaining bytes to 0. 
+@        remaining =  0;
+
+    @ Return the remaining number of bytes on the stack. 
+@    return(remaining);
+
+TCT_Skip_Stack_Check:
+        MOV     r0,r3                       @ Return remaining bytes
+
+        BX      r14                         @ Return to caller
+
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_Schedule                                                     
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function waits for a thread to become ready.  Once a thread 
+ *      is ready, this function initiates a transfer of control to that  
+ *      thread.                                                          
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      INC_Initialize                      Main initialization routine  
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      TCT_Control_To_Thread               Transfer control to a thread 
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      TCD_Execute_Task                    Pointer to task to execute   
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID  TCT_Schedule(void)
+@{
+
+	.globl  TCT_Schedule
+TCT_Schedule:
+
+    @ Restore interrupts according to the value contained in 
+@    TCD_Interrupt_Level.
+
+        LDR     r1,Int_Level                @ Build address of interrupt level
+        MRS     r0,CPSR                     @ Pickup current CPSR
+        LDR     r2,[r1, #0]                 @ Pickup current interrupt lockout
+        BIC     r0,r0,#LOCK_MSK             @ Clear the interrupt lockout bits
+        ORR     r0,r0,r2                    @ Build new interrupt lockout CPSR
+        MSR     CPSR,r0                     @ Setup new CPSR 
+        LDR     r2,Execute_HISR             @ Pickup TCD_Execute_HISR address
+        LDR     r3,Execute_Task             @ Pickup TCD_Execute_Task address
+
+#ifdef INCLUDE_PROVIEW
+@ Nucleus ProView Hook
+@ We check if upon entering TCT_Schedule we already have a task to excute.
+@ if not, we start IDLE.
+        LDR     r0,[r2, #0]                 @ Pickup highest priority HISR ptr
+        CMP     r0,#0                       @ Is there a HISR active?
+        BNE     TCT_Schedule_Thread         @ Found an HISR
+        LDR     r0,[r3, #0]                 @ Pickup highest priority Task ptr
+        CMP     r0,#0                       @ Is there a task active?
+        BNE     TCT_Schedule_Thread         @ If not, start IDLE.
+        STR     r2,[r13, #-4]!              @ Save r2 on the stack
+        STR     r3,[r13, #-4]!              @ Save r3 on the stack
+        BL      _NU_Idle_Hook
+        LDR     r3,[r13], #4                @ Recover r2
+        LDR     r2,[r13], #4                @ Recover r3
+#endif
+
+
+    @ Wait until a thread (task or HISR) is available to execute.
+@    do
+@    {
+TCT_Schedule_Loop:
+
+@    } while ((!TCD_Execute_HISR) && (!TCD_Execute_Task));
+
+        LDR     r0,[r2, #0]                 @ Pickup highest priority HISR ptr
+        CMP     r0,#0                       @ Is there a HISR active?
+        BNE     TCT_Schedule_Thread         @ Found an HISR
+        LDR     r0,[r3, #0]                 @ Pickup highest priority Task ptr
+        CMP     r0,#0                       @ Is there a task active?
+        BNE     TCT_Schedule_Thread
+@	stmfd	r13!,{r2-r3}
+@	BL	freecalypso_nucidle_dbghook
+@	ldmfd	r13!,{r2-r3}
+        B       TCT_Schedule_Loop
+
+    @ Yes, either a task or an HISR is ready to execute.  Lockout 
+    @ interrupts while the thread is transferred to.
+
+TCT_Schedule_Thread:
+        MRS     r1,CPSR                     @ Pickup CPSR again
+        ORR     r1,r1,#LOCKOUT              @ Build interrupt lockout value
+        MSR     CPSR,r1                     @ Lockout interrupts
+
+@ Transfer control to the thread by falling through to the following
+@ routine.
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_Control_To_Thread                                            
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function transfers control to the specified thread.  Each   
+ *      time control is transferred to a thread, its scheduled counter   
+ *      is incremented.  Additionally, time-slicing for task threads is  
+ *      enabled in this routine.  The TCD_Current_Thread pointer is      
+ *      setup by this function.                                          
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      TCT_Schedule                        Indirectly called            
+ *      TCT_Protect                         Protection task switch       
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      thread                              Thread control block pointer 
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID  TCT_Control_To_Thread(TC_TCB *thread)
+@{
+TCT_Control_To_Thread:
+
+    @ Setup the current thread pointer.
+@    TCD_Current_Thread =  (VOID *) thread;
+
+        LDR     r1,Current_Thread           @ Pickup current thread ptr address
+        LDR     r2,[r0, #0x1c]              @ Pickup scheduled count
+        STR     r0,[r1, #0]                 @ Setup current thread pointer
+
+    @ Increment the thread scheduled counter.
+@    thread -> tc_scheduled++;
+
+        LDR     r3,[r0, #0x20]              @ Pickup time slice value
+        ADD     r2,r2,#1                    @ Increment the scheduled count
+        STR     r2,[r0, #0x1c]              @ Store new scheduled count
+
+    @ Check for time slice option. 
+@    if (thread -> tc_cur_time_slice)
+@    {
+        CMP     r3,#0                       @ Is there a time slice?
+        BEQ     TCT_No_Start_TS_1           @ If 0, there is no time slice
+
+        @ Start a time slice.
+@        TMD_Time_Slice =        thread -> tc_cur_time_slice;
+@        TMD_Time_Slice_State =  0;
+
+        LDR     r2,Time_Slice               @ Pickup address of TMD_Time_Slice
+        LDR     r1,Slice_State              @ Pickup address of 
+                                            @ TMD_Time_Slice_State
+        STR     r3,[r2, #0]                 @ Setup the time slice
+        MOV     r2,#0                       @ Build active state flag
+        STR     r2,[r1,#0]                  @ Set the active flag
+@    }
+TCT_No_Start_TS_1:
+#ifdef INCLUDE_PROVIEW
+@    Nucleus ProView Hook
+
+        STR     r0,[r13, #-4]!              @ Save r0 on the stack
+        BL      _NU_Schedule_Task_Hook      @ Branch to RTView
+        LDR     r0,[r13], #4                @ Recover return address
+#endif
+
+
+    @ Pickup the stack pointer and resume the thread.
+@    REG_Stack_Ptr =  thread -> tc_stack_pointer;
+
+        LDR     r13,[r0, #0x2c]             @ Switch to thread's stack pointer
+
+@ Pop off the saved information associated with the thread. After we
+@ determine which type of stack is present.  A 1 on the top of the 
+@ stack indicates an interrupt stack, while a 0 on the top of the
+@ stack indicates a solicited type of stack.
+
+@ Remember that the interrupt level that is restored must represent
+@ the interrupt level in TCD_Interrupt_Level.
+
+        LDR     r1,[r13], #4                @ Pop off the stack type 
+        CMP     r1,#1                       @ See if it is an interrupt stack
+        BEQ     TCT_Interrupt_Resume        @ If so, an interrupt resume of
+                                            @ thread is required
+        LDR     r1, Int_Level               @ Pickup address of interrupt 
+                                            @ lockout
+        MRS     r0,CPSR                     @ Pickup current CPSR
+        BIC     r0,r0,#LOCK_MSK             @ Clear lockout mask
+
+        BIC     r0,r0,#0x80000000
+
+
+        LDR     r2,[r1, #0]                 @ Pickup interrupt lockout mask
+        ORR     r0,r0,r2                    @ Build new interrupt lockout mask
+#if 1	/* was .if THUMB */
+        LDR     r2,[r13], #4                @ Pop off the state mask
+        ORR     r0,r0,r2                    @ Set appropriate state 
+#endif
+        MSR     SPSR,r0                     @ Place it into the SPSR 
+        LDMIA   r13!,{r4-r12,r15}^          @ A solicited return is required.  
+                                            @ This type of return only 
+                                            @ recovers r4-r13 & r15
+TCT_Interrupt_Resume:
+        LDR     r0,[r13], #4                @ Pop off the CPSR
+        LDR     r1,Int_Level                @ Pickup address of interrupt 
+                                            @ lockout
+        BIC     r0,r0,#LOCK_MSK             @ Clear lockout mask
+        LDR     r2,[r1, #0]                 @ Pickup interrupt lockout mask
+        ORR     r0,r0,r2                    @ Build new interrupt lockout mask
+        MSR     SPSR,r0                     @ Place it into the SPSR 
+        LDMIA   r13,{r0-r15}^               @ Recover all registers and resume
+                                            @ at point of interrupt
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_Control_To_System                                            
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function returns control from a thread to the system.  Note 
+ *      that this service is called in a solicited manner, i.e. it is    
+ *      not called from an interrupt thread.  Registers required by the  
+ *      compiler to be preserved across function boundaries are saved by 
+ *      this routine.  Note that this is usually a sub-set of the total  
+ *      number of available registers.                                   
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      Other Components                                                 
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      TCT_Schedule                        Schedule the next thread     
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *      C. Meredith     03-01-1994      Corrected problem in time-slice  
+ *                                        reset logic, resulting in      
+ *                                        version 1.1                    
+ *      D. Lamie        03-18-1994      Verified version 1.1             
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID  TCT_Control_To_System(void)
+@{
+
+	.globl  TCT_Control_To_System
+TCT_Control_To_System:
+
+    @ Lockout interrupts. 
+
+        MRS     r0,CPSR                     @ Pickup current CPSR
+        ORR     r0,r0,#LOCKOUT              @ Build interrupt lockout value
+        MSR     CPSR,r0                     @ Lockout interrupts
+
+    @ Save a minimal context of the thread. 
+
+        STMDB   r13!,{r4-r12,r14}           @ Save minimal context of thread on
+                                            @ the current stack
+#if 1	/* was .if THUMB */
+        MOV     r2,r14                      @ Determine what state the caller
+        MOV     r2,r2,LSL #31               @ was in and build an
+        MOV     r2,r2,LSR #26               @ appropriate state mask
+        STR     r2,[r13, #-4]!              @ Place it on the stack
+#endif
+
+        MOV     r2,#0                       @ Build solicited stack type value
+                                            @ and NU_NULL value
+        STR     r2,[r13, #-4]!              @ Place it on the top of the stack
+
+    @ Setup a pointer to the thread control block. 
+@    REG_Thread_Ptr =  (TC_TCB *) TCD_Current_Thread;
+
+        LDR     r1,Current_Thread           @ Pickup current thread ptr address
+        LDR     r0,[r1, #0]                 @ Pickup current thread pointer
+
+    @ Clear the current thread control block pointer. 
+@    TCD_Current_Thread =  NU_NULL;
+
+        LDR     r3,Slice_State              @ Pickup time slice state address
+        STR     r2,[r1, #0]                 @ Set current thread pointer to 
+                                            @ NU_NULL
+
+@ Check to see if a time slice is active.  If so, copy the original time
+@ slice into the current time slice field of the task's control block.
+@    if (TMD_Time_Slice_State == 0)
+@    {
+        LDR     r1,[r3, #0]                 @ Pickup time slice state flag
+        CMP     r1,#0                       @ Compare with active value
+        BNE     TCT_No_Stop_TS_1            @ If non-active, don't disable
+
+    
+    @ Insure that the next time the task runs it gets a fresh time 
+    @ slice. 
+@       REG_Thread_Ptr -> tc_cur_time_slice =  REG_Thread_Ptr -> tc_time_slice;
+
+        LDR     r1,[r0, #0x40]              @ Pickup original time slice
+
+        @ Clear any active time slice by setting the state to NOT_ACTIVE. 
+@        TMD_Time_Slice_State =  1;
+
+        MOV     r2,#1                       @ Build disable value
+        STR     r2,[r3, #0]                 @ Disable time slice
+        STR     r1,[r0, #0x20]              @ Reset current time slice
+@    }
+TCT_No_Stop_TS_1:
+
+     @ Save off the current stack pointer in the control block. 
+@    REG_Thread_Ptr -> tc_stack_pointer =  (VOID *) REG_Stack_Ptr;
+
+        STR     r13,[r0, #0x2c]             @ Save the thread's stack pointer
+
+     @ Clear the task's current protection. 
+@    (REG_Thread_Ptr -> tc_current_protect) -> tc_tcb_pointer =  NU_NULL;
+@    REG_Thread_Ptr -> tc_current_protect =  NU_NULL;
+
+        LDR     r1,[r0, #0x38]              @ Pickup current thread pointer
+        MOV     r2,#0                       @ Build NU_NULL value
+        STR     r2,[r0, #0x38]              @ Clear the protect pointer field
+        STR     r2,[r1, #0]                 @ Release the actual protection
+
+    @ Switch to the system stack. 
+@    REG_Stack_Ptr =  TCD_System_Stack;
+
+        LDR     r1, System_Stack            @ Pickup address of stack pointer
+        LDR     r2, System_Limit            @ Pickup address of stack limit ptr
+        LDR     r13,[r1, #0]                @ Switch to system stack
+        LDR     r10,[r2, #0]                @ Setup system stack limit
+
+    @ Finished, return to the scheduling loop. 
+
+        B       TCT_Schedule                @ Return to scheduling loop
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_Signal_Exit                                                  
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function exits from a signal handler.  The primary purpose  
+ *      of this function is to clear the scheduler protection and switch 
+ *      the stack pointer back to the normal task's stack pointer.       
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      TCC_Signal_Shell                    Signal handling shell func   
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      TCT_Schedule                        Scheduler                    
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *      C. Meredith     03-01-1994      Corrected problem in time-slice  
+ *                                        reset logic, resulting in      
+ *                                        version 1.1                    
+ *      D. Lamie        03-18-1994      Verified version 1.1             
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID  TCT_Signal_Exit(void)
+@{
+
+	.globl  TCT_Signal_Exit
+TCT_Signal_Exit:
+
+    @ Lockout interrupts. 
+
+        MRS     r3,CPSR                     @ Pickup current CPSR
+        ORR     r3,r3,#LOCKOUT              @ Build lockout value
+        MSR     CPSR,r3                     @ Lockout interrupts
+
+    @ Setup a pointer to the thread control block. 
+@    REG_Thread_Ptr =  (TC_TCB *) TCD_Current_Thread;
+
+        LDR     r1,Current_Thread           @ Pickup address of thread pointer
+        MOV     r2,#0                       @ Build NU_NULL value
+        LDR     r0,[r1,#0]                  @ Pickup current thread pointer
+
+    @ Clear the current thread control block. 
+@    TCD_Current_Thread =  NU_NULL;
+
+        LDR     r3,Slice_State              @ Pickup time slice state address
+        STR     r2,[r1, #0]                 @ Clear current thread pointer
+
+    @ Check to see if a time slice is active.  If so, copy the original time
+    @ slice into the current time slice field of the task's control block.
+@    if (TMD_Time_Slice_State == 0)
+@    {
+
+        LDR     r1,[r3, #0]                 @ Pickup time slice state flag
+        CMP     r1,#0                       @ Compare with active value
+        BNE     TCT_No_Stop_TS_2            @ If non-active, don't disable
+
+        @ Insure that the next time the task runs it gets a fresh time 
+        @ slice. 
+@       REG_Thread_Ptr -> tc_cur_time_slice =  REG_Thread_Ptr -> tc_time_slice;
+
+        LDR     r1,[r0, #0x40]              @ Pickup original time slice
+
+        @ Clear any active time slice by setting the state to NOT_ACTIVE. 
+@        TMD_Time_Slice_State =  1;
+
+        MOV     r2,#1                       @ Build disable value
+        STR     r2,[r3, #0]                 @ Disable time slice
+        STR     r1,[r0, #0x20]              @ Reset current time slice
+@    }
+TCT_No_Stop_TS_2:
+
+    @ Switch back to the saved stack.  The saved stack pointer was saved
+    @ before the signal frame was built. 
+@    REG_Thread_Ptr -> tc_stack_pointer =  
+@                                REG_Thread_Ptr -> tc_saved_stack_ptr;
+
+        LDR     r1,[r0, #0x3c]              @ Pickup saved stack pointer
+        STR     r1,[r0, #0x2c]              @ Place in current stack pointer
+
+    @ Clear the task's current protection. 
+@    (REG_Thread_Ptr -> tc_current_protect) -> tc_tcb_pointer =  NU_NULL;
+@    REG_Thread_Ptr -> tc_current_protect =  NU_NULL;
+
+        LDR     r1,[r0, #0x38]              @ Pickup current thread pointer
+        MOV     r2,#0                       @ Build NU_NULL value
+        STR     r2,[r0, #0x38]              @ Clear the protect pointer field
+        STR     r2,[r1, #0]                 @ Release the actual protection
+
+    @ Switch to the system stack. 
+@    REG_Stack_Ptr =  (BYTE_PTR) TCD_System_Stack;
+
+        LDR     r1, System_Stack            @ Pickup address of stack pointer
+        LDR     r2, System_Limit            @ Pickup address of stack limit ptr
+        LDR     r13,[r1, #0]                @ Switch to system stack
+        LDR     r10,[r2, #0]                @ Setup system stack limit
+
+    @ Finished, return to the scheduling loop. 
+
+        B       TCT_Schedule                @ Return to scheduling loop
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_Current_Thread                                               
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function returns the current thread pointer.                
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      Application                                                      
+ *      System Components                                                
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      Pointer to current thread                                        
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID  *TCT_Current_Thread(void)
+@{
+
+	.globl  TCT_Current_Thread
+TCT_Current_Thread:
+
+    @ Return the current thread pointer. 
+@    return(TCD_Current_Thread);
+
+        LDR     r0, Current_Thread          @ Pickup address of thread pointer
+        LDR     r0,[r0, #0]                 @ Pickup current thread pointer
+
+        BX      r14                         @ Return to caller
+
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_Set_Execute_Task                                             
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function sets the current task to execute variable under    
+ *      protection against interrupts.                                   
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      TCC Scheduling Routines                                          
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      task                                Pointer to task control block
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      TCD_Execute_Task                    Modified variable            
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID  TCT_Set_Execute_Task(TC_TCB *task)
+@{
+
+	.globl  TCT_Set_Execute_Task
+TCT_Set_Execute_Task:
+
+    @ Now setup the TCD_Execute_Task pointer. 
+@    TCD_Execute_Task =  task;
+
+        LDR     r1, Execute_Task            @ Pickup execute task ptr address
+        STR     r0,[r1,#0]                  @ Setup new task to execute
+
+        BX      r14                         @ Return to caller
+
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_Protect                                                      
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function protects against multiple thread access.           
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      Application                                                      
+ *      System Components                                                
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      protect                            Pointer to protection block   
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID  TCT_Protect(TC_PROTECT *protect)
+@{
+
+	.globl  TCT_Protect
+TCT_Protect:
+
+    @ Determine if the caller is in a task or HISR thread. 
+@    if (TCD_Current_Thread)
+@    {
+
+        LDR     r1,Current_Thread           @ Pickup current thread ptr address
+        LDR     r3,[r1, #0]                 @ Pickup current thread pointer
+        CMP     r3,#0                       @ Check to see if it is non-NULL
+        BEQ     TCT_Skip_Protect            @ If NULL, skip protection
+
+        @ Lockout interrupts. 
+
+        MRS     r1,CPSR                     @ Pickup current CPSR
+        ORR     r1,r1,#LOCKOUT              @ Place lockout value in
+        MSR     CPSR,r1                     @ Lockout interrupts
+
+        @ Wait until the protect structure is available. 
+@        while (protect -> tc_tcb_pointer != NU_NULL)
+@        {
+
+TCT_Protect_Loop:
+        LDR     r1,[r0, #0]                 @ Pickup protection owner field
+        CMP     r1,#0                       @ Is there any protection?
+        BEQ     TCT_Protect_Available       @ If NU_NULL, no current protection
+
+        @ Protection structure is not available. 
+
+        @ Indicate that another thread is waiting. 
+@         protect -> tc_thread_waiting =  1;
+
+        MOV     r2,#1                       @ Build thread waiting flag
+        STR     r2,[r0, #4]                 @ Set waiting field
+
+        @ Directly schedule the thread waiting. 
+@       TCT_Schedule_Protected(protect -> tc_tcb_pointer);
+
+        STR     r0,[r13, #-4]!              @ Save r0 on the stack
+        STR     r14,[r13, #-4]!             @ Save r14 on the stack
+        MOV     r0,r3                       @ Place current thread into r0
+        BL      TCT_Schedule_Protected      @ Call routine to schedule the 
+                                            @ owner of the thread
+
+        LDR     r14,[r13], #4               @ Recover saved r14
+        LDR     r0,[r13], #4                @ Recover saved r0
+
+        @ Lockout interrupts. 
+
+        LDR     r1,Current_Thread           @ Pickup current thread ptr address
+        LDR     r3,[r1, #0]                 @ Pickup current thread pointer
+        MRS     r1,CPSR                     @ Pickup current CPSR
+        ORR     r1,r1,#LOCKOUT              @ Place lockout value in
+        MSR     CPSR,r1                     @ Lockout interrupts
+        B       TCT_Protect_Loop            @ Examine protect flags again
+@        }
+TCT_Protect_Available:
+
+        @ Protection structure is available. 
+    
+        @ Indicate that this thread owns the protection. 
+@        protect -> tc_tcb_pointer =  TCD_Current_Thread;
+
+        STR     r3,[r0, #0]                 @ Indicate calling thread owns this
+                                            @ protection
+
+        @ Clear the thread waiting flag. 
+@        protect -> tc_thread_waiting =  0;
+
+        MOV     r2,#0                       @ Clear value
+        STR     r2,[r0, #4]                 @ Clear the thread waiting flag
+
+@ Save the protection pointer in the thread's control block.  Note 
+@ that both task and HISR threads share the same control block 
+@ format. 
+@        REG_Thread_Ptr =  (TC_TCB *) TCD_Current_Thread;
+@        REG_Thread_Ptr -> tc_current_protect =  protect;
+
+        STR     r0,[r3, #0x38]              @ Setup current protection
+
+        @ Restore interrupts. 
+
+        LDR     r2,Int_Level                @ Pickup address of interrupt level
+        MRS     r1,CPSR                     @ Pickup current CPSR
+        LDR     r3,[r2, #0]                 @ Pickup interrupt lockout level
+        BIC     r1,r1,#LOCK_MSK             @ Clear lockout bits
+        ORR     r1,r1,r3                    @ Build new interrupt lockout
+        MSR     CPSR,r1                     @ Setup CPSR appropriately
+@    }
+
+TCT_Skip_Protect:
+
+        BX      r14                         @ Return to caller
+
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_Unprotect                                                    
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function releases protection of the currently active        
+ *      thread.  If the caller is not an active thread, then this        
+ *      request is ignored.                                              
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      Application                                                      
+ *      System Components                                                
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID  TCT_Unprotect(void)
+@{
+
+	.globl  TCT_Unprotect
+TCT_Unprotect:
+
+
+    @ Determine if the caller is in a task or HISR thread. 
+@    if (TCD_Current_Thread)
+@    {
+
+        LDR     r1,Current_Thread           @ Pickup current thread ptr address
+        LDR     r3,[r1, #0]                 @ Pickup current thread pointer
+        CMP     r3,#0                       @ Check to see if it is non-NULL
+        BEQ     TCT_Skip_Unprotect          @ If NULL, skip unprotection
+
+        @ Setup a thread control block pointer. 
+@        REG_Thread_Ptr =  (TC_TCB *) TCD_Current_Thread;
+
+        @ Determine if there is a currently active protection. 
+@        if (REG_Thread_Ptr -> tc_current_protect)
+@        {
+
+        LDR     r0,[r3, #0x38]              @ Pickup current protect field
+        CMP     r0,#0                       @ Is there a protection in force?
+        BEQ     TCT_Skip_Unprotect          @ If not, nothing is protected
+
+        @ Lockout interrupts. 
+
+        MRS     r1,CPSR                     @ Pickup current CPSR
+        ORR     r1,r1,#LOCKOUT              @ Place lockout value in
+        MSR     CPSR,r1                     @ Lockout interrupts
+
+        @ Yes, this thread still has this protection structure. 
+@            REG_Protect_Ptr =  REG_Thread_Ptr -> tc_current_protect;
+
+        @ Is there a higher priority thread waiting for the protection
+        @ structure? 
+@            if (REG_Protect_Ptr -> tc_thread_waiting)
+
+        LDR     r2,[r0, #4]                 @ Pickup thread waiting flag
+        CMP     r2,#0                       @ Are there any threads waiting?
+        BEQ     TCT_Not_Waiting_Unpr        @ If not, just release protection
+
+@                Transfer control to the system.  Note that this 
+@                   automatically clears the current protection and it returns
+@                   to the caller of this routine instead of this routine. 
+@                TCT_Control_To_System();
+
+        B       TCT_Control_To_System       @ Return control to the system
+
+@            else
+@            {
+TCT_Not_Waiting_Unpr:
+
+        @ Clear the protection. 
+@                REG_Thread_Ptr -> tc_current_protect =  NU_NULL;
+@                REG_Protect_Ptr -> tc_tcb_pointer =  NU_NULL;
+
+        MOV     r2,#0                       @ Build NU_NULL value
+        STR     r2,[r0, #0]                 @ Release the protection
+        STR     r2,[r3, #0x38]              @ Clear protection pointer in the
+                                            @ control block
+
+@            }
+
+TCT_Not_Protected:
+        @ Restore interrupts again. 
+
+        LDR     r2,Int_Level                @ Pickup address of interrupt level
+        MRS     r1,CPSR                     @ Pickup current CPSR
+        LDR     r3,[r2, #0]                 @ Pickup interrupt lockout level
+        BIC     r1,r1,#LOCK_MSK             @ Clear lockout bits
+        ORR     r1,r1,r3                    @ Build new interrupt lockout
+        MSR     CPSR,r1                     @ Setup CPSR appropriately
+
+@        }
+@    }
+TCT_Skip_Unprotect:
+
+        BX      r14                         @ Return to caller
+
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_Unprotect_Specific                                           
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function releases a specific protection structure.          
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      Application                                                      
+ *      System Components                                                
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      protect                            Pointer to protection block   
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *      C. Meredith     03-01-1994      Corrected problem in time-slice  
+ *                                        reset logic, corrected bug     
+ *                                        using protect ptr, resulting   
+ *                                        in version 1.1                 
+ *      D. Lamie        03-18-1994      Verified version 1.1             
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID  Specific(TC_PROTECT *protect)
+@{
+
+	.globl  TCT_Unprotect_Specific
+TCT_Unprotect_Specific:
+
+    @ Determine if the caller is in a task or HISR thread. 
+@    if (TCD_Current_Thread)
+@    {
+
+        LDR     r1,Current_Thread           @ Pickup current thread ptr address
+        LDR     r3,[r1, #0]                 @ Pickup current thread pointer
+        CMP     r3,#0                       @ Check to see if it is non-NULL
+        BEQ     TCT_Skip_Unprot_Spec        @ If NULL, skip unprotect specific
+
+        @ Lockout interrupts. 
+
+        MRS     r1,CPSR                     @ Pickup current CPSR
+        ORR     r1,r1,#LOCKOUT              @ Place lockout value in
+        MSR     CPSR,r1                     @ Lockout interrupts
+
+        @ Clear the protection pointer. 
+@        protect -> tc_tcb_pointer =  NU_NULL;
+
+        MOV     r2,#0                       @ Build NU_NULL value
+        STR     r2,[r0, #0]                 @ Clear protection ownership
+
+        @ Determine if a thread is waiting. 
+@        if (protect -> tc_thread_waiting)
+@        {
+
+        LDR     r1,[r0, #4]                 @ Pickup the waiting field
+        CMP     r1,#0                       @ Is there another thread waiting?
+        BEQ     TCT_Not_Waiting_Unspec      @ No, restore interrupts and return
+
+        @ A higher-priority thread is waiting. 
+
+        @ Save a minimal context of the thread. 
+
+        STMDB   r13!,{r4-r12,r14}           @ Save minimal context of thread on
+                                            @ the current stack
+
+#if 1	/* was .if THUMB */
+        MOV     r2,r14                      @ Determine what state the caller
+        MOV     r2,r2,LSL #31               @ was in and build an
+        MOV     r2,r2,LSR #26               @ appropriate state mask
+        STR     r2,[r13, #-4]!              @ Place it on the stack
+#endif
+
+        MOV     r2,#0                       @ Build solicited stack type value
+                                            @ and NU_NULL value
+        STR     r2,[r13, #-4]!              @ Place it on the top of the stack
+
+        @ Setup a pointer to the thread control block. 
+@            REG_Thread_Ptr =  (TC_TCB *) TCD_Current_Thread;
+
+        LDR     r1,Current_Thread           @ Pickup current thread ptr address
+        LDR     r0,[r1, #0]                 @ Pickup current thread pointer
+
+        @ Clear the current thread control block pointer. 
+@            TCD_Current_Thread =  NU_NULL;
+
+        LDR     r3,Slice_State              @ Pickup time slice state address
+        STR     r2,[r1, #0]                 @ Set current thread pointer to 
+                                            @ NU_NULL
+
+        @ Check to see if a time slice is active.  If so, copy the 
+        @ original time slice into the current time slice field of the 
+        @ thread's control block.
+@            if (TMD_Time_Slice_State == 0)
+@            {
+
+        LDR     r1,[r3, #0]                 @ Pickup time slice state flag
+        CMP     r1,#0                       @ Compare with active value
+        BNE     TCT_No_Stop_TS_3            @ If non-active, don't disable
+
+        @ Insure that the next time the task runs it gets a fresh time
+        @ slice. 
+@                REG_Thread_Ptr -> tc_cur_time_slice =  
+@                                        REG_Thread_Ptr -> tc_time_slice;
+
+        LDR     r1,[r0, #0x40]              @ Pickup original time slice
+
+        @ Clear any active time slice by setting the state to 
+        @ NOT_ACTIVE. 
+@                TMD_Time_Slice_State =  1;
+
+        MOV     r2,#1                       @ Build disable value
+        STR     r2,[r3, #0]                 @ Disable time slice
+        STR     r1,[r0, #0x20]              @ Reset current time slice
+@            }
+
+TCT_No_Stop_TS_3:
+
+        @ Save off the current stack pointer in the control block. 
+@            REG_Thread_Ptr -> tc_stack_pointer =  (VOID *) REG_Stack_Ptr;
+
+        STR     r13,[r0, #0x2c]             @ Save the thread's stack pointer
+
+        @ Switch to the system stack. 
+@            REG_Stack_Ptr =  TCD_System_Stack;
+
+        LDR     r1,System_Stack             @ Pickup address of stack pointer
+        LDR     r2,System_Limit             @ Pickup address of stack limit ptr
+        LDR     r13,[r1, #0]                @ Switch to system stack
+        LDR     r10,[r2, #0]                @ Setup system stack limit
+
+        @ Finished, return to the scheduling loop. 
+
+        B       TCT_Schedule                @ Return to scheduling loop
+
+@        }
+@        else
+@        {
+TCT_Not_Waiting_Unspec:
+
+        @ No higher-priority thread is waiting. 
+
+@            Restore interrupts. 
+
+        LDR     r2,Int_Level                @ Pickup address of interrupt level
+        MRS     r1,CPSR                     @ Pickup current CPSR
+        LDR     r3,[r2, #0]                 @ Pickup interrupt lockout level
+        BIC     r1,r1,#LOCK_MSK             @ Clear lockout bits
+        ORR     r1,r1,r3                    @ Build new interrupt lockout
+        MSR     CPSR,r1                     @ Setup CPSR appropriately
+
+@        }
+@    }
+
+TCT_Skip_Unprot_Spec:
+
+        BX      r14                         @ Return to caller
+
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_Set_Current_Protect                                          
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function sets the current protection field of the current   
+ *      thread's control block to the specified protection pointer.      
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      TCC_Resume_Task                    Resume task function          
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      protect                            Pointer to protection block   
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID  TCT_Set_Current_Protect(TC_PROTECT *protect)
+@{
+
+	.globl  TCT_Set_Current_Protect
+TCT_Set_Current_Protect:
+
+    @ Determine if the caller is in a task or HISR thread. 
+@    if (TCD_Current_Thread)
+@    {
+
+        LDR     r1,Current_Thread           @ Pickup current thread ptr address
+        LDR     r3,[r1, #0]                 @ Pickup current thread pointer
+        CMP     r3,#0                       @ Check to see if a thread is 
+                                            @ active
+
+        @ Point at the current thread control block. 
+@        REG_Thread_Ptr =  (TC_TCB *) TCD_Current_Thread;
+
+        @ Modify the current protection. 
+@        REG_Thread_Ptr -> tc_current_protect =  protect;
+
+        STRNE   r0,[r3, #0x38]              @ Setup new protection
+@    }
+
+
+        BX      r14                         @ Return to caller
+
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_Protect_Switch                                               
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function waits until a specific task no longer has any      
+ *      protection associated with it.  This is necessary since task's   
+ *      cannot be suspended or terminated unless they have released all  
+ *      of their protection.                                             
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      System Components                                                
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      thread                             Pointer to thread control blk 
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID  TCT_Protect_Switch(VOID *thread)
+@{
+
+	.globl  TCT_Protect_Switch
+TCT_Protect_Switch:
+
+        @ Lockout interrupts. 
+
+        MRS     r1,CPSR                     @ Pickup current CPSR
+        ORR     r1,r1,#LOCKOUT              @ Place lockout value in
+        MSR     CPSR,r1                     @ Lockout interrupts
+
+@    REG_Thread_Ptr =  (TC_TCB *) thread;
+
+    @ Wait until the specified task has no protection associated with it. 
+@    while (REG_Thread_Ptr -> tc_current_protect)
+@    {
+
+        LDR     r1,[r0, #0x38]              @ Pickup protection of specified
+                                            @ thread
+        CMP     r1,#0                       @ Does the specified thread have
+                                            @ an active protection?
+        BEQ     TCT_Switch_Done             @ If not, protect switch is done
+
+        @ Let the task run again in an attempt to clear its protection. 
+
+        @ Indicate that a higher priority thread is waiting. 
+@        (REG_Thread_Ptr -> tc_current_protect) -> tc_thread_waiting =  1;
+
+        MOV     r2,#1                       @ Build waiting flag value
+        STR     r2,[r1, #4]                 @ Set waiting flag of the 
+                                            @ protection owned by the other
+                                            @ thread
+
+        @ Directly schedule the thread waiting. 
+@        TCT_Schedule_Protected((REG_Thread_Ptr -> tc_current_protect)  
+@                                                        -> tc_tcb_pointer);
+
+        LDR     r2,Current_Thread           @ Pickup current thread ptr address
+        STR     r0,[r13, #-4]!              @ Save r0 on the stack
+        STR     r14,[r13, #-4]!             @ Save r14 on the stack
+        MOV     r1,r0                       @ Move new thread into r1
+        LDR     r0,[r2, #0]                 @ Pickup current thread pointer
+        BL      TCT_Schedule_Protected      @ Call routine to schedule the 
+                                            @ owner of the thread
+
+        LDR     r14,[r13], #4               @ Recover saved r14
+        LDR     r0,[r13], #4                @ Recover saved r0
+
+        @ Lockout interrupts. 
+
+        B       TCT_Protect_Switch          @ Branch to top of routine and 
+                                            @ start over
+@    }
+TCT_Switch_Done:
+
+        @ Restore interrupts. 
+
+        LDR     r2,Int_Level                @ Pickup address of interrupt level
+        MRS     r1,CPSR                     @ Pickup current CPSR
+        LDR     r3,[r2, #0]                 @ Pickup interrupt lockout level
+        BIC     r1,r1,#LOCK_MSK             @ Clear lockout bits
+        ORR     r1,r1,r3                    @ Build new interrupt lockout
+        MSR     CPSR,r1                     @ Setup CPSR appropriately
+
+
+        BX      r14                         @ Return to caller
+
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_Schedule_Protected                                           
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function saves the minimal context of the thread and then   
+ *      directly schedules the thread that has protection over the       
+ *      the thread that called this routine.                             
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      TCT_Protect                                                      
+ *      TCT_Protect_Switch                                               
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      TCT_Control_To_Thread               Transfer control to protected
+ *                                              thread                   
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *      C. Meredith     03-01-1994      Corrected problem in time-slice  
+ *                                        reset logic, resulting in      
+ *                                        version 1.1                    
+ *      D. Lamie        03-18-1994      Verified version 1.1             
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID  TCT_Schedule_Protected(VOID *thread)
+@{
+
+	.globl	TCT_Schedule_Protected
+TCT_Schedule_Protected:
+
+    @ Interrupts are already locked out by the caller. 
+
+    @ Save minimal context required by the system. 
+
+        STMDB   r13!,{r4-r12,r14}           @ Save minimal context of thread on
+                                            @ the current stack
+
+#if 1	/* was .if THUMB */
+        MOV     r2,r14                      @ Determine what state the caller
+        MOV     r2,r2,LSL #31               @ was in and build an
+        MOV     r2,r2,LSR #26               @ appropriate state mask
+        STR     r2,[r13, #-4]!              @ Place it on the stack
+#endif
+
+        MOV     r2,#0                       @ Build solicited stack type value
+                                            @ and NU_NULL value
+        STR     r2,[r13, #-4]!              @ Place it on the top of the stack
+        MOV     r4,r1                       @ Save thread to schedule
+
+    @ Setup a pointer to the thread control block. 
+@    REG_Thread_Ptr =  (TC_TCB *) TCD_Current_Thread;
+
+        LDR     r1,Current_Thread           @ Pickup current thread ptr address
+
+    @ Clear the current thread control block. 
+@    TCD_Current_Thread =  NU_NULL;
+
+        LDR     r3,Slice_State              @ Pickup time slice state address
+        STR     r2,[r1, #0]                 @ Set current thread pointer to 
+                                            @ NU_NULL
+
+    @ Check to see if a time slice is active.  If so, copy the original time
+    @ slice into the current time slice field of the task's control block.
+@    if (TMD_Time_Slice_State == 0)
+@    {
+
+        LDR     r1,[r3, #0]                 @ Pickup time slice state flag
+        CMP     r1,#0                       @ Compare with active value
+        BNE     TCT_No_Stop_TS_4            @ If non-active, don't disable
+
+    @ Insure that the next time the task runs it gets a fresh time 
+    @ slice. 
+@       REG_Thread_Ptr -> tc_cur_time_slice =  REG_Thread_Ptr -> tc_time_slice;
+
+        LDR     r1,[r0, #0x40]              @ Pickup original time slice
+
+    @ Clear any active time slice by setting the state to NOT_ACTIVE. 
+@        TMD_Time_Slice_State =  1;
+
+        MOV     r2,#1                       @ Build disable value
+        STR     r2,[r3, #0]                 @ Disable time slice
+        STR     r1,[r0, #0x20]              @ Reset current time slice
+
+@    }
+TCT_No_Stop_TS_4:
+
+    @ Save off the current stack pointer in the control block. 
+@    REG_Thread_Ptr -> tc_stack_pointer =  (VOID *) REG_Stack_Ptr;
+
+        STR     r13,[r0, #0x2c]             @ Save the thread's stack pointer
+
+    @ Switch to the system stack. 
+@    TCD_System_Stack =  (VOID *) REG_Stack_Ptr;
+
+        LDR     r1,System_Stack             @ Pickup address of stack pointer
+        LDR     r2,System_Limit             @ Pickup address of stack limit ptr
+        LDR     r13,[r1, #0]                @ Switch to system stack
+        LDR     r10,[r2, #0]                @ Setup system stack limit
+
+    @ Transfer control to the specified thread directly.
+@    TCT_Control_To_Thread(thread);
+
+        LDR     r2,Int_Level                @ Pickup address of interrupt level
+        MRS     r1,CPSR                     @ Pickup current CPSR
+        LDR     r3,[r2, #0]                 @ Pickup interrupt lockout level
+        BIC     r1,r1,#LOCK_MSK             @ Clear lockout bits
+        ORR     r1,r1,r3                    @ Build new interrupt lockout
+        MOV     r0,r4                       @ Indicate thread to schedule
+        MSR     CPSR,r1                     @ Setup CPSR appropriately
+        ORR     r1,r1,#LOCKOUT              @ Build lockout value again
+        MSR     CPSR,r1                     @ Lockout interrupts again
+        B       TCT_Control_To_Thread       @ Schedule the thread indirectly
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_Interrupt_Context_Save                                       
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function saves the interrupted thread's context.  Nested    
+ *      interrupts are also supported.  If a task or HISR thread was     
+ *      interrupted, the stack pointer is switched to the system stack   
+ *      after the context is saved.                                      
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      Application ISRs                    Assembly language ISRs       
+ *      INT_Interrupt_Shell                 Interrupt handler shell      
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      vector                              Interrupt's vector number    
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *      D. Driscoll     01-04-2002      Released version 1.13.3.         
+ *                                      Updated to handle nested /       
+ *                                      prioritized IRQs                 
+ ************************************************************************
+ */
+
+@VOID  TCT_Interrupt_Context_Save(INT vector)
+@{
+
+	.globl  TCT_Interrupt_Context_Save
+TCT_Interrupt_Context_Save:
+        @ Determine if this is a nested interrupt. 
+        LDR     r1,Int_Count                @ Pickup address of interrupt count
+        LDR     r2,[r1, #0]                 @ Pickup interrupt counter
+        ADD     r2,r2,#1                    @ Add 1 to interrupt counter
+        STR     r2,[r1, #0]                 @ Store new interrupt counter value
+        CMP     r2,#1                       @ Is it nested?
+        BEQ     TCT_Not_Nested_Save         @ No
+
+@ Nested interrupt.  Save complete context on the current stack. 
+TCT_Nested_Save:
+
+/* No longer needed in the FreeCalypso version, as we can use r0 instead. */
+#if 0
+@       1.  Save another register on the exception stack so we have enough to work with
+        STMDB   r13!,{r5}
+#endif
+
+@       2.  Save the necessary exception registers into r1-r3
+        MOV     r1,r13                      @ Put the exception r13 into r1
+        MOV     r2,r14                      @ Move the return address for the caller
+                                            @  of this function into r2
+        MRS     r3,spsr                     @ Put the exception spsr into r3
+
+@       3.  Adjust the exception stack pointer for future exceptions
+        ADD     r13,r13,#20                 @ r13 reset to pre-interrupt value
+
+@       4.  Switch CPU modes to save context on system stack
+        MRS     r0,CPSR                     @ Pickup the current CPSR
+        BIC     r0,r0,#MODE_MASK            @ Clear the mode bits
+        
+        ORR     r0,r0,#SUP_MODE             @ Change to supervisor mode (SVD)
+        
+        MSR     CPSR,r0                     @ Switch modes (IRQ->SVC)
+
+@       5.  Store the SVC r13 into r5 so the r13 can be saved as is.
+@	FreeCalyspo: using r0 instead
+        MOV     r0,r13
+
+@       6.  Save the exception return address on the stack (r15).
+        STMDB   r0!,{r4}
+
+@       7.  Save r5-r14 on stack (used to be r6-r14)
+        STMDB   r0!,{r5-r14}
+
+@       8.  Switch back to using r13 now that the original r13 has been saved.
+        MOV     r13,r0
+
+/* no longer relevant */
+#if 0
+@       9.  Get r5 and exception enable registers off of exception stack and
+@              save r5 (stored in r4) back to the system stack.
+        LDMIA   r1!,{r4-r5}
+        STMDB   r13!,{r4}
+        MOV     r4,r5                       @ Put exception enable value into r4
+#endif
+
+@       10. Get the rest of the registers off the exception stack and
+@              save them onto the system stack.
+        LDMIA   r1!,{r5-r8,r11}             @ Get r0-r4 off exception stack
+        STMDB   r13!,{r5-r8,r11}            @ Put r0-r4 on system stack
+
+/* no longer relevant */
+#if 0
+@       11. Store the exception enable value back on the exception stack.
+        STMDB   r1,{r4}
+#endif
+
+@       12. Save the SPSR on the system stack (CPSR)
+        STMDB   r13!,{r3}
+
+/* TI's approach to interrupt handling does not support re-enabling here */
+#if 0
+@       13. Re-enable interrupts
+        MRS     r1,CPSR
+        BIC     r1,r1,#(IRQ_BIT_OR_FIQ_BIT)
+        MSR     CPSR,r1
+#endif
+
+        BX      r2                          @ Return to calling ISR
+@    }
+@    else
+@    {
+TCT_Not_Nested_Save:
+
+        @ Determine if a thread was interrupted. 
+@       if (TCD_Current_Thread)
+@       {
+
+        LDR     r1,Current_Thread           @ Pickup current thread ptr address
+        LDR     r1,[r1, #0]                 @ Pickup the current thread pointer
+        CMP     r1,#0                       @ Is it NU_NULL?
+        BEQ     TCT_Idle_Context_Save       @ If no, no real save is necessary
+
+
+        @ Yes, a thread was interrupted.  Save complete context on the
+        @ thread's stack. 
+
+/* No longer needed in the FreeCalypso version, as we can use r0 instead. */
+#if 0
+@       1.  Save another register on the exception stack so we have enough to work with
+        STMDB   r13!,{r5}
+#endif
+
+@       2.  Save the necessary exception registers into r1-r3
+        MOV     r1,r13                      @ Put the exception r13 into r1
+        MOV     r2,r14                      @ Move the return address for the caller
+                                            @  of this function into r2
+        MRS     r3,spsr                     @ Put the exception spsr into r3
+
+@       3.  Adjust the exception stack pointer for future exceptions
+        ADD     r13,r13,#20                 @ r13 reset to pre-interrupt value
+
+@       4.  Switch CPU modes to save context on system stack
+        MRS     r0,CPSR                     @ Pickup the current CPSR
+        BIC     r0,r0,#MODE_MASK            @ Clear the mode bits
+        
+        ORR     r0,r0,#SUP_MODE             @ Change to supervisor mode (SVD)
+        
+        MSR     CPSR,r0                     @ Switch modes (IRQ->SVC)
+
+@       5.  Store the SVC r13 into r5 so the r13 can be saved as is.
+@	FreeCalyspo: using r0 instead
+        MOV     r0,r13
+
+@       6.  Save the exception return address on the stack (r15).
+        STMDB   r0!,{r4}
+
+@       7.  Save r5-r14 on stack (used to be r6-r14)
+        STMDB   r0!,{r5-r14}
+
+@       8.  Switch back to using r13 now that the original r13 has been saved.
+        MOV     r13,r0
+
+/* no longer relevant */
+#if 0
+@       9. Get r5 and exception enable registers off of exception stack and
+@          save r5 (stored in r4) back to the system stack.
+        LDMIA   r1!,{r4-r5}
+        STMDB   r13!,{r4}
+        MOV     r4,r5                       @ Put exception enable value into r4
+#endif
+
+@       10. Get the rest of the registers off the exception stack and
+@           save them onto the system stack.
+        LDMIA   r1!,{r5-r8,r11}             @ Get r0-r4 off exception stack
+        STMDB   r13!,{r5-r8,r11}            @ Put r0-r4 on system stack
+
+/* no longer relevant */
+#if 0
+@       11. Store the exception enable value back on the exception stack.
+        STMDB   r1,{r4}
+#endif
+
+@       12. Save the SPSR on the system stack (CPSR)
+        STMDB   r13!,{r3}
+
+@       13. Save stack type to the task stack (1=interrupt stack)
+        MOV     r1,#1                       @ Interrupt stack type
+        STMDB   r13!,{r1}
+
+        @ Save the thread's stack pointer in the control block. 
+@       REG_Thread_Ptr =  (TC_TCB *) TCD_Current_Thread
+@       REG_Thread_Ptr -> tc_stack_pointer =  (VOID *) REG_Stack_Ptr
+
+        LDR     r1,Current_Thread           @ Pickup current thread ptr address
+        LDR     r3,[r1, #0]                 @ Pickup current thread pointer
+        STR     r13,[r3, #TC_STACK_POINTER] @ Save stack pointer
+
+        @ Switch to the system stack. 
+@            REG_Stack_Ptr =  TCD_System_Stack
+
+        LDR     r1,System_Stack             @ Pickup address of stack pointer
+        LDR     r3,System_Limit             @ Pickup address of stack limit ptr
+        LDR     r13,[r1, #0]                @ Switch to system stack
+        LDR     r10,[r3, #0]                @ Setup system stack limit
+
+/* TI's approach to interrupt handling does not support re-enabling here */
+#if 0
+        @ Re-enable interrupts
+        MRS     r1,CPSR
+        BIC     r1,r1,#(IRQ_BIT_OR_FIQ_BIT)
+        MSR     CPSR,r1
+#endif
+ 
+@ Return to caller ISR. 
+
+        BX      r2                          @ Return to caller ISR
+
+@       }
+
+TCT_Idle_Context_Save:
+
+        MOV     r2,r14                      @ Save r14 in r2
+@       LDR     r3,[r13]                    @ Get exception enable value from stack
+        ADD     r13,r13,#20                 @ Adjust exception r13 for future interrupts
+@       STR     r3,[r13]                    @ Put exception enable value back on stack
+
+        MRS     r1,CPSR                     @ Pickup current CPSR
+        BIC     r1,r1,#MODE_MASK            @ Clear the current mode
+@       BIC     r1,r1,#(IRQ_BIT_OR_FIQ_BIT) @ Re-enable interrupts
+        
+        ORR     r1,r1,#SUP_MODE             @ Prepare to switch to supervisor
+                                            @   mode (SVC)
+        MSR     CPSR,r1                     @ Switch to supervisor mode (SVC)
+
+        BX      r2                          @ Return to caller ISR
+
+@    }
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_Interrupt_Context_Restore                                    
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function restores the interrupt context if a nested         
+ *      interrupt condition is present.  Otherwise, this routine         
+ *      transfers control to the scheduling function.                    
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      Application ISRs                    Assembly language ISRs       
+ *      INT_Interrupt_Shell                 Interrupt handler shell      
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      TCT_Schedule                        Thread scheduling function   
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *      D. Driscoll     01-04-2002      Released version 1.13.3.         
+ *                                      Updated to handle nested /       
+ *                                      prioritized IRQs                 
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID  TCT_Interrupt_Context_Restore(void)
+@{
+
+	.globl  TCT_Interrupt_Context_Restore
+TCT_Interrupt_Context_Restore:
+    @ It is assumed that anything pushed on the stack by ISRs has been
+    @ removed upon entry into this routine. 
+
+    @ Decrement and check for nested interrupt conditions. 
+@    if (--TCD_Interrupt_Count)
+@    {
+
+        LDR     r1,Int_Count                @ Pickup address of interrupt count
+        LDR     r2,[r1, #0]                 @ Pickup interrupt counter
+        SUB     r2,r2,#1                    @ Decrement interrupt counter
+        STR     r2,[r1, #0]                 @ Store interrupt counter
+        CMP     r2,#0
+        BEQ     TCT_Not_Nested_Restore
+
+        @ Restore previous context. 
+
+        LDR     r1,[r13], #4                @ Pickup the saved CPSR
+        
+        MSR     SPSR,r1                     @ Place into saved SPSR
+        LDMIA   r13,{r0-r15}^               @ Return to the point of interrupt
+
+@    }
+@    else
+@    {
+
+TCT_Not_Nested_Restore:
+
+        @ Determine if a thread is active. 
+@        if (TCD_Current_Thread)
+@        {
+
+        LDR     r1,Current_Thread           @ Pickup current thread ptr address
+        LDR     r0,[r1, #0]                 @ Pickup current thread pointer
+        CMP     r0,#0                       @ Determine if a thread is active
+        BEQ     TCT_Idle_Context_Restore    @ If not, idle system restore
+
+        @ Clear the current thread pointer. 
+@            TCD_Current_Thread =  NU_NULL
+
+        MOV     r2,#0                       @ Build NU_NULL value
+        STR     r2,[r1, #0]                 @ Set current thread ptr to NU_NULL
+
+        @ Determine if a time slice is active.  If so, the remaining
+        @ time left on the time slice must be saved in the task's
+        @ control block. 
+@            if (TMD_Time_Slice_State == 0)
+@            {
+
+        LDR     r3,Slice_State              @ Pickup time slice state address
+        LDR     r1,[r3, #0]                 @ Pickup time slice state
+        CMP     r1,#0                       @ Determine if time slice active
+        BNE     TCT_Idle_Context_Restore    @ If not, skip time slice reset
+
+        @ Pickup the remaining portion of the time slice and save it
+        @ in the task's control block. 
+@                REG_Thread_Ptr -> tc_cur_time_slice =  TMD_Time_Slice
+@                TMD_Time_Slice_State =  1
+
+        LDR     r2,Time_Slice               @ Pickup address of time slice left
+        MOV     r1,#1                       @ Build disable time slice value
+        LDR     r2,[r2, #0]                 @ Pickup remaining time slice
+        STR     r1,[r3, #0]                 @ Disable time slice
+        STR     r2,[r0, #TC_CUR_TIME_SLICE] @ Store remaining time slice
+
+@            }
+@        }
+TCT_Idle_Context_Restore:
+
+        @ Reset the system stack pointer. 
+        LDR     r1,System_Stack             @ Pickup address of stack pointer
+        LDR     r2,System_Limit             @ Pickup address of stack limit ptr
+        LDR     r13,[r1, #0]                @ Switch to system stack
+        LDR     r10,[r2, #0]                @ Setup system stack limit
+
+        @ Return to scheduler. 
+
+        B       TCT_Schedule                @ Return to scheduling loop
+
+@    }
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_Activate_HISR                                                
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function activates the specified HISR.  If the HISR is      
+ *      already activated, the HISR's activation count is simply         
+ *      incremented.  Otherwise, the HISR is placed on the appropriate   
+ *      HISR priority list in preparation for execution.                 
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      Application LISRs                                                
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      hisr                                Pointer to HISR to activate  
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      NU_SUCCESS                          Successful completion        
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *                                                                       
+ ************************************************************************
+ */
+
+@STATUS  TCT_Activate_HISR(TC_HCB *hisr)
+@{
+
+	.globl  TCT_Activate_HISR
+TCT_Activate_HISR:
+
+@INT     priority;
+
+
+        @ Lockout interrupts. 
+
+        STR     r4,[r13, #-4]!              @ Save r4
+        MRS     r4,CPSR                     @ Pickup current CPSR
+        ORR     r1,r4,#LOCKOUT              @ Build interrupt lockout value
+        MSR     CPSR,r1                     @ Lockout interrupts
+
+    @ Determine if the HISR is already active. 
+@    if (hisr -> tc_activation_count)
+@    {
+
+        LDR     r1,[r0,#0x40]               @ Pickup current activation count
+        CMP     r1,#0                       @ Is it the first activation?
+        BEQ     TCT_First_Activate          @ Yes, place it on the correct list
+
+    @ Increment the activation count.  Make sure that it does not go
+    @ to zero. 
+@        hisr -> tc_activation_count++;
+
+        ADDS    r1,r1,#1                    @ Increment the activation count
+        STR     r1,[r0,#0x40]               @ Store new activation count
+
+@        if (hisr -> tc_activation_count == 0)
+
+@            hisr -> tc_activation_count =  0xFFFFFFFFUL;
+
+        MVNEQ   r1,#0                       @ If counter rolled-over reset
+        STREQ   r1,[r0,#0x40]               @ Store all ones count
+        B       TCT_Activate_Done           @ Finished with activation
+@    }
+@    else
+@    {
+TCT_First_Activate:
+
+
+        @ Set the activation count to 1. 
+@        hisr -> tc_activation_count =  1;
+
+        MOV     r1,#1                       @ Initial activation count
+        STR     r1,[r0,#0x40]               @ Store initial activation count
+
+        @ Pickup the HISR's priority. 
+@        priority =  hisr -> tc_priority;
+
+        @ Determine if there is something in the given priority list. 
+@        if (TCD_Active_HISR_Tails[priority])
+@        {
+
+        LDRB    r1,[r0,#0x1a]               @ Pickup priority of HISR
+        LDR     r2,HISR_Tails               @ Pickup tail pointer base
+        LDR     r3,[r2,r1,LSL #2]           @ Pickup tail pointer for priority
+        CMP     r3,#0                       @ Is this first HISR at priority?
+        BEQ     TCT_First_HISR              @ No, append to end of HISR list
+
+        @ Something is already on this list.  Add after the tail. 
+@            (TCD_Active_HISR_Tails[priority]) -> tc_active_next =  hisr;
+@            TCD_Active_HISR_Tails[priority] =  hisr;
+
+        STR     r0,[r3,#0x3c]               @ Setup the active next pointer
+        STR     r0,[r2,r1,LSL #2]           @ Setup the tail pointer
+        B       TCT_Activate_Done           @ Finished with activate processing
+@        }
+@        else
+@        {
+TCT_First_HISR:
+
+        @ Nothing is on this list. 
+@           TCD_Active_HISR_Heads[priority] =  hisr;
+@           TCD_Active_HISR_Tails[priority] =  hisr;
+
+        LDR     r3,HISR_Heads               @ Pickup address of head pointers
+        STR     r0,[r2,r1,LSL #2]           @ Set tail pointer to this HISR
+        STR     r0,[r3,r1,LSL #2]           @ Set head pointer to this HISR
+
+        @ Determine the highest priority HISR. 
+@           if (TCD_Active_HISR_Heads[0])
+@               TCD_Execute_HISR =  TCD_Active_HISR_Heads[0];
+@           else if (TCD_Active_HISR_Heads[1])
+@               TCD_Execute_HISR =  TCD_Active_HISR_Heads[1];
+@           else
+@               TCD_Execute_HISR =  TCD_Active_HISR_Heads[2];
+
+        LDR     r1,[r3,#0]                  @ Pickup priority 0 head pointer
+        LDR     r0,Execute_HISR             @ Build address to execute HISR ptr
+        CMP     r1,#0                       @ Is priority 0 active?
+        LDREQ   r1,[r3,#4]                  @ If not, pickup priority 1 head 
+        CMPEQ   r1,#0                       @ Is priority 1 active?
+        LDREQ   r1,[r3,#8]                  @ Else, must be priority 2 active
+        STR     r1,[r0,#0]                  @ Store which ever priority is the
+                                            @   active one
+@       }
+@    }
+TCT_Activate_Done:
+
+        MSR     CPSR,r4                     @ Restore interrupt lockout
+        LDR     r4,[r13], #4                @ Restore corrupted r4
+
+@    return(NU_SUCCESS);
+
+        MOV     r0,#0                       @ Always return NU_SUCCESS
+
+        BX      r14                         @ Return to caller
+
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      TCT_HISR_Shell                                                   
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function is the execution shell of each and every HISR.  If 
+ *      the HISR has completed its processing, this shell routine exits  
+ *      back to the system.  Otherwise, it sequentially calls the HISR   
+ *      routine until the activation count goes to zero.                 
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      HISR Scheduling                                                  
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      hisr -> tc_entry                    Actual entry function of HISR
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        02-15-1994      Created initial version 1.0      
+ *      D. Lamie        02-15-1994      Verified version 1.0             
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID    TCT_HISR_Shell(void)
+@{
+        .globl  TCT_HISR_Shell
+TCT_HISR_Shell:
+
+    @ Point at the HISR. 
+@    REG_HISR_Ptr =  (TC_HCB *) TCD_Current_Thread;
+
+        LDR     r0,Current_Thread            @ Build address of thread pointer
+        LDR     r5,[r0, #0]                  @ Pickup control block pointer
+
+@    do
+@    {
+TCT_HISR_Loop:
+
+        @ Call the HISR's entry routine. 
+@        (*(REG_HISR_Ptr -> tc_entry)) ();
+
+/* old TMS470 code:
+
+        .if THUMB = 0
+
+         MOV     r14,r15                     ; Setup return value
+         LDR     r15,[r5,#44h]               ; Call HISR entry function
+        .else
+         LDR     r4,[r5,#44h]                ; Get HISR entry function
+         TST     r4,#1                       ; See if calling Thumb or ARM
+         BNE     Thumbsec
+         MOV     r14,r15                     ; Setup return value
+         BX      r4
+         B       ARMCODE
+Thumbsec:
+         ADD     r14, r15, #1 
+         BX      r4
+         .state16
+ThumbAfterHisr
+         MOV     r1, r15  
+         BX      r1
+        .state32
+        .endif
+*/
+
+	/* new code for the GNU style of ARM/Thumb interworking */
+	ldr	r4, [r5, #TC_HISR_ENTRY]
+	mov	lr, pc
+	bx	r4
+
+        @ Lockout interrupts. 
+
+        MRS     r1,CPSR                     @ Pickup current CPSR
+        ORR     r1,r1,#LOCKOUT              @ Build interrupt lockout 
+        MSR     CPSR,r1                     @ Lockout interrupts
+
+        @ On return, decrement the activation count and check to see if 
+        @ it is 0.  Once it reaches 0, the HISR should be made inactive.
+@        REG_HISR_Ptr -> tc_activation_count--;
+
+
+        LDR     r0,[r5, #0x40]              @ Pickup current activation count
+        SUBS    r0,r0,#1                    @ Subtract and set condition codes
+        STR     r0,[r5, #0x40]              @ Store new activation count
+        BEQ     TCT_HISR_Finished           @ Finished processing HISR
+
+        @ Restore interrupts. 
+
+        LDR     r2,Int_Level                @ Pickup address of interrupt level
+        MRS     r1,CPSR                     @ Pickup current CPSR
+        LDR     r3,[r2, #0]                 @ Pickup interrupt lockout level
+        BIC     r1,r1,#LOCK_MSK             @ Clear lockout bits
+        ORR     r1,r1,r3                    @ Build new interrupt lockout
+        MSR     CPSR,r1                     @ Setup CPSR appropriately
+        B       TCT_HISR_Loop               @ Return to HISR loop
+@    }
+@    while (REG_HISR_Ptr -> tc_activation_count);
+
+TCT_HISR_Finished:
+
+        @ At this point, the HISR needs to be made inactive. 
+
+        @ Determine if this is the only HISR on the given priority list. 
+@    if (REG_HISR_Ptr == TCD_Active_HISR_Tails[REG_HISR_Ptr -> tc_priority])
+@    {
+
+        LDR     r14,HISR_Tails               @ Pickup tail pointers address
+        LDRB    r3,[r5,#0x1a]                @ Pickup priority
+        LDR     r6,[r14,r3,LSL #2]           @ Pickup this priority tail pointer
+        LDR     r2,Execute_HISR              @ Build address to execute HISR ptr
+        MOV     r12,#0                       @ Clear r12
+        LDR     r1,HISR_Heads                @ Pickup head pointers address
+        CMP     r6,r5                        @ Is this priority tail the same as
+                                             @ the current HISR?
+        BNE     TCT_More_HISRs               @ If not, more HISRs at this 
+                                             @ priority
+
+        @ The only HISR on the list.  Clean up the list and check for the
+        @ highest priority HISR. 
+@       TCD_Active_HISR_Heads[REG_HISR_Ptr -> tc_priority] =  NU_NULL;
+@       TCD_Active_HISR_Tails[REG_HISR_Ptr -> tc_priority] =  NU_NULL;
+
+        STR     r12,[r1,r3,LSL #2]            @ Set head pointer to NU_NULL
+        STR     r12,[r14,r3,LSL #2]           @ Set tail pointer to NU_NULL
+
+        @ Determine the highest priority HISR. 
+@       if (TCD_Active_HISR_Heads[0])
+@           TCD_Execute_HISR =  TCD_Active_HISR_Heads[0];
+@       else if (TCD_Active_HISR_Heads[1])
+@           TCD_Execute_HISR =  TCD_Active_HISR_Heads[1];
+@       else
+@           TCD_Execute_HISR =  TCD_Active_HISR_Heads[2];
+
+        LDR     r3,[r1,#0]                    @ Pickup priority 0 head pointer
+        CMP     r3,#0                         @ Is there an HISR active?
+        LDREQ   r3,[r1,#4]                    @ If not, pickup priority 1 pointer
+        CMPEQ   r3,#0                         @ Is there an HISR active?
+        LDREQ   r3,[r1,#8]                    @ If not, pickup priority 2 pointer
+        STR     r3,[r2,#0]                    @ Setup execute HISR pointer
+        B       TCT_HISR_Exit                 @ Exit HISR processing
+@    }
+@    else
+@    {
+
+TCT_More_HISRs:
+
+        @ Move the head pointer to the next HISR in the list. 
+@        TCD_Active_HISR_Heads[REG_HISR_Ptr -> tc_priority] =  
+@                                        REG_HISR_Ptr -> tc_active_next;
+
+        @ Also set the TCD_Execute_HISR pointer. 
+@        TCD_Execute_HISR =  REG_HISR_Ptr -> tc_active_next;
+
+        LDR     r14,[r5,#0x3c]                @ Pickup next HISR to activate
+        STR     r14,[r1,r3,LSL #2]            @ Setup new head pointer
+        STR     r14,[r2, #0]                  @ Setup execute HISR pointer
+@    }
+
+TCT_HISR_Exit:
+
+        @ Build fake return to the top of this loop.  The next time the HISR
+        @ is activated, it will return to the top of this function. 
+
+        LDR     r14,HISR_Shell                @ Pickup address of shell entry
+        STMDB   r13!,{r4-r12,r14}             @ Save minimal context of thread on
+                                              @ the current stack
+        MOV     r2,#0                         @ Build solicited stack type value
+                                              @ and NU_NULL value
+#if 1	/* was .if THUMB */
+        STR     r2,[r13, #-4]!                @ Save state mask
+#endif
+        STR     r2,[r13, #-4]!                @ Place it on the top of the stack
+
+        @ Clear the current thread control block. 
+@    TCD_Current_Thread =  NU_NULL;
+
+        LDR     r1,Current_Thread            @ Pickup current thread ptr address
+        STR     r2,[r1, #0]                  @ Set current thread pointer to 
+                                             @   NU_NULL
+
+        @ Save off the current stack pointer in the control block. 
+@    REG_HISR_Ptr -> tc_stack_pointer =  (VOID *) REG_Stack_Ptr;
+
+         
+        STR     r13,[r5, #0x2c]              @ Save the thread's stack pointer
+
+
+        @ Switch to the system stack. 
+@    REG_Stack_Ptr =  (BYTE_PTR) TCD_System_Stack;
+
+        LDR     r1,System_Stack              @ Pickup address of stack pointer
+        LDR     r2,System_Limit              @ Pickup address of stack limit ptr
+        LDR     r13,[r1, #0]                 @ Switch to system stack
+        LDR     r10,[r2, #0]                 @ Setup system stack limit
+
+        @ Transfer control to the main scheduling loop. 
+
+        B       TCT_Schedule                 @ Return to main scheduling loop
+@}
+
+/* FreeCalypso addition, used by riviera/rvf/rvf_task.c: */
+	.globl	INT_Check_IRQ_Mask
+INT_Check_IRQ_Mask:
+	MRS	r0,CPSR
+	BX	lr
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nuc-fw/nucleus/debug-chases/tms.c.dbg	Mon Nov 11 10:17:08 2013 +0000
@@ -0,0 +1,637 @@
+/*************************************************************************/
+/*                                                                       */
+/*               Copyright Mentor Graphics Corporation 2002              */
+/*                         All Rights Reserved.                          */
+/*                                                                       */
+/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS  */
+/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS   */
+/* SUBJECT TO LICENSE TERMS.                                             */
+/*                                                                       */
+/*************************************************************************/
+
+/*************************************************************************/
+/*                                                                       */
+/* FILE NAME                                               VERSION       */
+/*                                                                       */
+/*      tms.c                                          Nucleus PLUS 1.14 */
+/*                                                                       */
+/* COMPONENT                                                             */
+/*                                                                       */
+/*      TM - Timer Management                                            */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This file contains supplemental routines for the timer           */
+/*      management component.                                            */
+/*                                                                       */
+/* DATA STRUCTURES                                                       */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* FUNCTIONS                                                             */
+/*                                                                       */
+/*      TMS_Create_Timer                    Create an application timer  */
+/*      TMS_Delete_Timer                    Delete an application timer  */
+/*      TMS_Reset_Timer                     Reset application timer      */
+/*      TMS_Control_Timer                   Enable/Disable application   */
+/*                                            timer                      */
+/*                                                                       */
+/* DEPENDENCIES                                                          */
+/*                                                                       */
+/*      cs_extr.h                           Common Service functions     */
+/*      tc_extr.h                           Thread Control functions     */
+/*      tm_extr.h                           Timer functions              */
+/*      hi_extr.h                           History functions            */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1994      Created initial version 1.1 from                 */
+/*                        previous version of TMC.C                      */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*      04-17-1996      updated to version 1.2                           */
+/*      03-24-1998      Released version 1.3.                            */
+/*      03-26-1999      Released 1.11m (new release                      */
+/*                        numbering scheme)                              */
+/*      04-17-2002      Released version 1.13m                           */
+/*      11-07-2002      Released version 1.14                            */
+/*************************************************************************/
+#define         NU_SOURCE_FILE
+
+
+#include        "cs_extr.h"                 /* Common service functions  */
+#include        "tc_extr.h"                 /* Thread control functions  */
+#include        "tm_extr.h"                 /* Timer functions           */
+#include        "hi_extr.h"                 /* History functions         */
+#include        "profiler.h"                /* ProView interface         */
+
+
+/* Define external inner-component global data references.  */
+
+extern CS_NODE        *TMD_Created_Timers_List;
+extern UNSIGNED        TMD_Total_Timers;
+extern TM_TCB         *TMD_Active_Timers_List;
+extern INT             TMD_Active_List_Busy;
+extern TC_PROTECT      TMD_Created_List_Protect;
+
+
+/* Define internal function prototypes.  */
+
+VOID            TMC_Start_Timer(TM_TCB *timer, UNSIGNED time);
+VOID            TMC_Stop_Timer(TM_TCB *timer);
+
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TMS_Create_Timer                                                 */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function creates an application timer and places it on the  */
+/*      list of created timers.  The timer is activated if designated by */
+/*      the enable parameter.                                            */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*      TMSE_Create_Timer                   Error checking shell         */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      CSC_Place_On_List                   Add node to linked-list      */
+/*      [HIC_Make_History_Entry]            Make entry in history log    */
+/*      [TCT_Check_Stack]                   Stack checking function      */
+/*      TCT_Protect                         Data structure protect       */
+/*      TCT_Unprotect                       Un-protect data structure    */
+/*      TMS_Control_Timer                   Enable the new timer         */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      timer_ptr                           Timer control block pointer  */
+/*      name                                Timer name                   */
+/*      expiration_routine                  Timer expiration routine     */
+/*      id                                  Timer expiration ID          */
+/*      initial_time                        Initial expiration time      */
+/*      reschedule_time                     Reschedule expiration time   */
+/*      enable                              Automatic enable option      */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      NU_SUCCESS                                                       */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Changed function prototype,                      */
+/*                        resulting in version 1.1                       */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+STATUS  TMS_Create_Timer(NU_TIMER *timer_ptr, CHAR *name,
+                VOID (*expiration_routine)(UNSIGNED), UNSIGNED id,
+                UNSIGNED initial_time, UNSIGNED reschedule_time, OPTION enable)
+{
+
+R1 TM_APP_TCB  *timer;                      /* Timer control block ptr   */
+INT             i;                          /* Working index variable    */
+NU_SUPERV_USER_VARIABLES
+
+    /* Switch to supervisor mode */
+    NU_SUPERVISOR_MODE();
+
+    /* Move input timer pointer into internal pointer.  */
+    timer =  (TM_APP_TCB *) timer_ptr;
+
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+#ifdef  NU_ENABLE_HISTORY
+
+    /* Make an entry that corresponds to this function in the system history
+       log.  */
+    HIC_Make_History_Entry(NU_CREATE_TIMER_ID, (UNSIGNED) timer,
+                               (UNSIGNED) name, (UNSIGNED) expiration_routine);
+
+#endif
+
+    /* First, clear the timer ID just in case it is an old Timer
+       Control Block.  */
+    timer -> tm_id =             0;
+
+    /* Fill in the timer name.  */
+    for (i = 0; i < NU_MAX_NAME; i++)
+        timer -> tm_name[i] =  name[i];
+
+    /* Load the timer with the appropriate values.  */
+    timer -> tm_expiration_routine =            expiration_routine;
+    timer -> tm_expiration_id =                 id;
+    timer -> tm_expirations =                   0;
+    timer -> tm_initial_time =                  initial_time;
+    timer -> tm_reschedule_time =               reschedule_time;
+    timer -> tm_actual_timer.tm_timer_type =    TM_APPL_TIMER;
+    timer -> tm_enabled =                       NU_FALSE;
+
+    /* Initialize link pointers.  */
+    timer -> tm_created.cs_previous =           NU_NULL;
+    timer -> tm_created.cs_next =               NU_NULL;
+    timer -> tm_actual_timer.tm_next_timer =    NU_NULL;
+    timer -> tm_actual_timer.tm_previous_timer= NU_NULL;
+    timer -> tm_actual_timer.tm_information =   (VOID *) timer;
+
+    /* Protect against access to the list of created timers.  */
+    TCT_Protect(&TMD_Created_List_Protect);
+
+    /* At this point the timer is completely built.  The ID can now be
+       set and it can be linked into the created timer list.  */
+    timer -> tm_id =                     TM_TIMER_ID;
+
+    /* Link the timer into the list of created timers and increment the
+       total number of timers in the system.  */
+    CSC_Place_On_List(&TMD_Created_Timers_List, &(timer -> tm_created));
+    TMD_Total_Timers++;
+
+#ifdef INCLUDE_PROVIEW
+    _RTProf_DumpTimer(RT_PROF_CREATE_TIMER,timer,RT_PROF_OK);
+#endif
+
+    /* Release protection against access to the list of created timers.  */
+    TCT_Unprotect();
+
+    /* Determine if the timer should be enabled.  */
+    if (enable == NU_ENABLE_TIMER)
+
+        /* Activate the timer.  */
+        TMS_Control_Timer(timer_ptr, NU_ENABLE_TIMER);
+
+    /* Return to user mode */
+    NU_USER_MODE();
+
+    /* Return successful completion.  */
+    return(NU_SUCCESS);
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TMS_Delete_Timer                                                 */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function deletes an application timer and removes it from   */
+/*      the list of created timers.                                      */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*      TMSE_Delete_Timer                   Error checking shell         */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      CSC_Remove_From_List                Remove node from list        */
+/*      [HIC_Make_History_Entry]            Make entry in history log    */
+/*      [TCT_Check_Stack]                   Stack checking function      */
+/*      TCT_Protect                         Protect created list         */
+/*      TCT_System_Protect                  Protect active list          */
+/*      TCT_Unprotect                       Release protection           */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      timer_ptr                           Timer control block pointer  */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      NU_NOT_DISABLED                     Timer not disabled first     */
+/*      NU_SUCCESS                                                       */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Modified protection logic to use                 */
+/*                        system protection, changed                     */
+/*                        function prototype, resulting                  */
+/*                        in version 1.1                                 */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+STATUS  TMS_Delete_Timer(NU_TIMER *timer_ptr)
+{
+
+TM_APP_TCB     *timer;                      /* Timer control block ptr  */
+STATUS          status;                     /* Completion status        */
+NU_SUPERV_USER_VARIABLES
+
+    /* Switch to supervisor mode */
+    NU_SUPERVISOR_MODE();
+
+    /* Move input timer pointer into internal pointer.  */
+    timer =  (TM_APP_TCB *) timer_ptr;
+
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+#ifdef  NU_ENABLE_HISTORY
+
+    /* Make an entry that corresponds to this function in the system history
+       log.  */
+    HIC_Make_History_Entry(NU_DELETE_TIMER_ID, (UNSIGNED) timer,
+                                        (UNSIGNED) 0, (UNSIGNED) 0);
+
+#endif
+
+    /* Initialize the status.  */
+    status =  NU_SUCCESS;
+
+    /* Use system protect to protect the active timer list temporarily.  */
+    TCT_System_Protect();
+
+    /* Determine if the timer is currently disabled. */
+    if (timer -> tm_enabled)
+    {
+        /* Error, indicate to the caller that the timer is currently active. */
+        status =  NU_NOT_DISABLED;
+
+#ifdef INCLUDE_PROVIEW
+        _RTProf_DumpTimer(RT_PROF_DELETE_TIMER,timer,RT_PROF_FAIL);
+#endif
+
+    }
+    else
+    {
+        /* Clear the timer ID.  */
+        timer -> tm_id =  0;
+
+#ifdef INCLUDE_PROVIEW
+        _RTProf_DumpTimer(RT_PROF_DELETE_TIMER,timer,RT_PROF_OK);
+#endif /* INCLUDE_PROVIEW */
+
+    }
+
+    /* Release protection.  */
+    TCT_Unprotect();
+
+    /* Determine if an error was detected.  */
+    if (status == NU_SUCCESS)
+    {
+
+        /* Protect against access to the list of created timers.  */
+        TCT_Protect(&TMD_Created_List_Protect);
+
+        /* Remove the timer from the list of created timers.  */
+        CSC_Remove_From_List(&TMD_Created_Timers_List, &(timer -> tm_created));
+
+        /* Decrement the total number of created timers.  */
+        TMD_Total_Timers--;
+
+        /* Release protection against access to the list of created timers.  */
+        TCT_Unprotect();
+    }
+
+    /* Return to user mode */
+    NU_USER_MODE();
+
+    /* Return completion status.  */
+    return(status);
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TMS_Reset_Timer                                                  */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function resets the specified application timer.  Note that */
+/*      the timer must be in a disabled state prior to this call.  The   */
+/*      timer is activated after it is reset if the enable parameter     */
+/*      specifies automatic activation.                                  */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*      TMSE_Reset_Timer                    Error checking shell         */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      [HIC_Make_History_Entry]            Make entry in history log    */
+/*      [TCT_Check_Stack]                   Stack checking function      */
+/*      TCT_System_Protect                  Protect active list          */
+/*      TCT_Unprotect                       Release protection           */
+/*      TMS_Control_Timer                   Enable/disable timer         */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      timer_ptr                           Timer control block pointer  */
+/*      expiration_routine                  Timer expiration routine     */
+/*      initial_time                        Initial expiration time      */
+/*      reschedule_time                     Reschedule expiration time   */
+/*      enable                              Automatic enable option      */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      NU_NOT_DISABLED                     Timer not disabled first     */
+/*      NU_SUCCESS                          Successful completion        */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Modified protection logic to use                 */
+/*                        system protection, changed                     */
+/*                        function prototype, resulting                  */
+/*                        in version 1.1                                 */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+STATUS  TMS_Reset_Timer(NU_TIMER *timer_ptr,
+                VOID (*expiration_routine)(UNSIGNED),
+                UNSIGNED initial_time, UNSIGNED reschedule_time, OPTION enable)
+{
+
+R1 TM_APP_TCB  *timer;                      /* Timer control block ptr  */
+STATUS          status;                     /* Completion status        */
+NU_SUPERV_USER_VARIABLES
+static char dbgstr[512];
+
+	sprintf(dbgstr, "* TMS_Reset_Timer(): timer_ptr=%08x, expiration_routine=%08x, initial_time=%x, reschedule_time=%x, enable=%x",
+		(unsigned)timer_ptr, (unsigned)expiration_routine,
+		(unsigned)initial_time, (unsigned)reschedule_time,
+		(unsigned)enable);
+	freecalypso_raw_dbgout(dbgstr);
+
+    /* Switch to supervisor mode */
+    NU_SUPERVISOR_MODE();
+
+    /* Move input timer pointer into internal pointer.  */
+    timer =  (TM_APP_TCB *) timer_ptr;
+
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+#ifdef  NU_ENABLE_HISTORY
+
+    /* Make an entry that corresponds to this function in the system history
+       log.  */
+    HIC_Make_History_Entry(NU_RESET_TIMER_ID, (UNSIGNED) timer,
+                       (UNSIGNED) expiration_routine, (UNSIGNED) initial_time);
+
+#endif
+
+    /* Protect against access to the active timer list.  */
+    TCT_System_Protect();
+
+    /* Determine if this timer is active.  An active timer cannot be
+       reset.  */
+    if (timer -> tm_enabled)
+    {
+
+        /* Indicate that the timer is active by returning the proper status. */
+        status =  NU_NOT_DISABLED;
+
+#ifdef INCLUDE_PROVIEW
+        _RTProf_DumpTimer(RT_PROF_RESET_TIMER,timer,RT_PROF_FAIL);
+#endif /* INCLUDE_PROVIEW */
+
+    }
+    else
+    {
+
+        /* Load the timer with the appropriate values.  */
+        timer -> tm_expiration_routine =    expiration_routine;
+        timer -> tm_expirations =           0;
+        timer -> tm_initial_time =          initial_time;
+        timer -> tm_reschedule_time =       reschedule_time;
+
+        /* Indicate successful completion status.  */
+        status =  NU_SUCCESS;
+#ifdef INCLUDE_PROVIEW
+        _RTProf_DumpTimer(RT_PROF_RESET_TIMER,timer,RT_PROF_OK);
+#endif /* INCLUDE_PROVIEW */
+
+    }
+
+    /* Release protection.  */
+    TCT_Unprotect();
+
+    /* Determine if the timer needs to be enabled.  */
+    if ((status == NU_SUCCESS) && (enable == NU_ENABLE_TIMER))
+
+        /* Activate the timer.  */
+        TMS_Control_Timer(timer_ptr, NU_ENABLE_TIMER);
+
+    /* Return to user mode */
+    NU_USER_MODE();
+
+    /* Return completion status.  */
+    return(status);
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TMS_Control_Timer                                                */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function either enables or disables the specified timer.    */
+/*      If the timer is already in the desired state, simply leave it    */
+/*      alone.                                                           */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*      TMSE_Control_Timer                Error checking shell           */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      [HIC_Make_History_Entry]            Make entry in history log    */
+/*      [TCT_Check_Stack]                   Stack checking function      */
+/*      TCT_System_Protect                  Protect the active list      */
+/*      TCT_Unprotect                       Release protection           */
+/*      TMC_Start_Timer                     Start a timer                */
+/*      TMC_Stop_Timer                      Stop a timer                 */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      app_timer                           Timer control block pointer  */
+/*      enable                              Disable/enable timer option  */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      NU_SUCCESS                          If service is successful     */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Modified protection logic to use                 */
+/*                        system protection, changed                     */
+/*                        function prototype, resulting                  */
+/*                        in version 1.1                                 */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+STATUS  TMS_Control_Timer(NU_TIMER *app_timer, OPTION enable)
+{
+
+R1 TM_APP_TCB  *timer;                      /* Timer control block ptr   */
+TM_TCB         *timer_ptr;                  /* Actual timer pointer      */
+UNSIGNED        time;                       /* Variable to hold request  */
+NU_SUPERV_USER_VARIABLES
+
+    /* Switch to supervisor mode */
+    NU_SUPERVISOR_MODE();
+
+    /* Move input timer pointer into internal pointer.  */
+    timer =  (TM_APP_TCB *) app_timer;
+
+
+#ifdef  NU_ENABLE_STACK_CHECK
+
+    /* Call stack checking function to check for an overflow condition.  */
+    TCT_Check_Stack();
+
+#endif
+
+#ifdef  NU_ENABLE_HISTORY
+
+    /* Make an entry that corresponds to this function in the system history
+       log.  */
+    HIC_Make_History_Entry(NU_CONTROL_TIMER_ID, (UNSIGNED) timer,
+                                        (UNSIGNED) enable, (UNSIGNED) 0);
+
+#endif
+
+    /* Protect against simultaneous access to the active timer list.  */
+    TCT_System_Protect();
+
+    /* Setup pointer to actual timer part of the control block.  */
+    timer_ptr =  &(timer -> tm_actual_timer);
+
+    /* Determine what type of request is present.  */
+    if ((enable == NU_ENABLE_TIMER) && (!timer -> tm_enabled))
+    {
+
+        /* Enable timer request is present and timer is currently disabled.  */
+
+        /* Determine how to setup the remaining field in the actual timer. */
+        if (timer -> tm_expirations)
+
+            /* Use reschedule time since this timer has expired previously. */
+            time =  timer -> tm_reschedule_time;
+        else
+
+            /* Use initial time since this timer has never expired.  */
+            time =  timer -> tm_initial_time;
+
+        /* Mark the application timer as enabled.  */
+        timer -> tm_enabled =  NU_TRUE;
+
+        /* Call the start timer routine to actually start the timer.  */
+        TMC_Start_Timer(&(timer -> tm_actual_timer), time);
+    }
+    else if ((enable == NU_DISABLE_TIMER) && (timer -> tm_enabled))
+    {
+
+        /* Disable timer request is present and timer is currently enabled.  */
+        TMC_Stop_Timer(timer_ptr);
+
+        /* Mark the timer as disabled.  */
+        timer -> tm_enabled =  NU_FALSE;
+    }
+
+#ifdef INCLUDE_PROVIEW
+        _RTProf_DumpTimer(RT_PROF_CONTROL_TIMER,timer,RT_PROF_OK);
+#endif /* INCLUDE_PROVIEW */
+    /* Release protection.  */
+    TCT_Unprotect();
+
+    /* Return to user mode */
+    NU_USER_MODE();
+
+    /* Return the completion status.  */
+    return(NU_SUCCESS);
+}
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nuc-fw/nucleus/debug-chases/tmse.c.dbg	Mon Nov 11 10:17:08 2013 +0000
@@ -0,0 +1,427 @@
+/*************************************************************************/
+/*                                                                       */
+/*               Copyright Mentor Graphics Corporation 2002              */
+/*                         All Rights Reserved.                          */
+/*                                                                       */
+/* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS  */
+/* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS   */
+/* SUBJECT TO LICENSE TERMS.                                             */
+/*                                                                       */
+/*************************************************************************/
+
+/*************************************************************************/
+/*                                                                       */
+/* FILE NAME                                               VERSION       */
+/*                                                                       */
+/*      tmse.c                                         Nucleus PLUS 1.14 */
+/*                                                                       */
+/* COMPONENT                                                             */
+/*                                                                       */
+/*      TM - Timer Management                                            */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This file contains the error checking routines for the functions */
+/*      in the Timer component.  This permits easy removal of error      */
+/*      checking logic when it is not needed.                            */
+/*                                                                       */
+/* DATA STRUCTURES                                                       */
+/*                                                                       */
+/*      None                                                             */
+/*                                                                       */
+/* FUNCTIONS                                                             */
+/*                                                                       */
+/*      TMSE_Create_Timer                   Create an application timer  */
+/*      TMSE_Delete_Timer                   Delete an application timer  */
+/*      TMSE_Reset_Timer                    Reset application timer      */
+/*      TMSE_Control_Timer                  Enable/Disable application   */
+/*                                            timer                      */
+/*                                                                       */
+/* DEPENDENCIES                                                          */
+/*                                                                       */
+/*      cs_extr.h                           Common Service functions     */
+/*      tm_extr.h                           Timer functions              */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Changed names of error checking                  */
+/*                      shell to match new conventions,                  */
+/*                      resulting in version 1.1                         */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*      04-17-1996      updated to version 1.2                           */
+/*      03-24-1998      Released version 1.3                             */
+/*      04-17-2002      Released version 1.13m                           */
+/*      11-07-2002      Released version 1.14                            */
+/*************************************************************************/
+#define         NU_SOURCE_FILE
+
+
+#include        "cs_extr.h"                 /* Common service functions  */
+#include        "tm_extr.h"                 /* Timer functions           */
+
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TMSE_Create_Timer                                                */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function performs error checking on the parameters supplied */
+/*      to the create timer function.                                    */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      TMS_Create_Timer                    Actual create timer function */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      timer_ptr                           Timer control block pointer  */
+/*      name                                Timer name                   */
+/*      expiration_routine                  Timer expiration routine     */
+/*      id                                  Timer expiration ID          */
+/*      initial_time                        Initial expiration time      */
+/*      reschedule_time                     Reschedule expiration time   */
+/*      enable                              Automatic enable option      */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      NU_INVALID_TIMER                    Indicates timer pointer is   */
+/*                                            NULL                       */
+/*      NU_INVALID_FUNCTION                 Indicates timer expiration   */
+/*                                            function pointer is NULL   */
+/*      NU_INVALID_ENABLE                   Indicates enable parameter   */
+/*                                            is invalid                 */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Changed function interface,                      */
+/*                      resulting in version 1.1                         */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+STATUS  TMSE_Create_Timer(NU_TIMER *timer_ptr, CHAR *name, 
+                VOID (*expiration_routine)(UNSIGNED), UNSIGNED id,
+                UNSIGNED initial_time, UNSIGNED reschedule_time, OPTION enable)
+{
+
+TM_APP_TCB     *timer;                      /* Timer control block ptr  */
+STATUS          status;                     /* Completion status        */
+
+
+    /* Move input timer pointer into internal pointer.  */
+    timer =  (TM_APP_TCB *) timer_ptr;
+
+    /* Check the parameters to the create timer function.  */
+    if ((timer == NU_NULL) || (timer -> tm_id == TM_TIMER_ID))
+    
+        /* Invalid timer pointer.  */
+        status =  NU_INVALID_TIMER;
+    
+    else if (expiration_routine == NU_NULL)
+    
+        /* Invalid expiration function pointer.  */
+        status =  NU_INVALID_FUNCTION;
+
+    else if (initial_time == 0)
+    
+        /* Invalid time value.  */
+        status =  NU_INVALID_OPERATION;
+
+        
+    else if ((enable != NU_ENABLE_TIMER) && (enable != NU_DISABLE_TIMER))
+    
+        /* Invalid enable parameter.  */
+        status =  NU_INVALID_ENABLE;
+        
+    else
+    
+        /* Call the actual create timer function.  */
+        status =  TMS_Create_Timer(timer_ptr, name, expiration_routine, id,
+                                      initial_time, reschedule_time, enable);
+
+    /* Return the completion status.  */
+    return(status);
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TMSE_Delete_Timer                                                */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function performs error checking on the parameters supplied */
+/*      to the delete timer function.                                    */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      TMS_Delete_Timer                    Actual delete timer function */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      timer_ptr                           Timer control block pointer  */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      NU_INVALID_TIMER                    Indicates the timer pointer  */
+/*                                            is NULL or not a timer     */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*        DATE                    REMARKS                                */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Changed function interface,                      */
+/*                      resulting in version 1.1                         */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+STATUS  TMSE_Delete_Timer(NU_TIMER *timer_ptr)
+{
+
+TM_APP_TCB     *timer;                      /* Timer control block ptr  */
+STATUS          status;                     /* Completion status        */
+
+    
+    /* Move input timer pointer into internal pointer.  */
+    timer =  (TM_APP_TCB *) timer_ptr;
+
+    /* Check the parameters to the delete timer function.  */
+    if (timer == NU_NULL)
+    
+        /* Invalid timer pointer.  */
+        status =  NU_INVALID_TIMER;
+    
+    else if (timer -> tm_id != TM_TIMER_ID)
+    
+        /* Invalid timer pointer.  */
+        status =  NU_INVALID_TIMER;
+    
+    else
+    
+        /* Call the actual delete timer function.  */
+        status =  TMS_Delete_Timer(timer_ptr);
+
+    /* Return completion status.  */
+    return(status);
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TMSE_Reset_Timer                                                 */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function performs error checking on the parameters supplied */
+/*      to the reset timer function.                                     */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      TMS_Reset_Timer                     Actual reset timer function  */
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      timer_ptr                           Timer control block pointer  */
+/*      expiration_routine                  Timer expiration routine     */
+/*      initial_time                        Initial expiration time      */
+/*      reschedule_time                     Reschedule expiration time   */
+/*      enable                              Automatic enable option      */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      NU_INVALID_TIMER                    Indicates timer pointer is   */
+/*                                            invalid                    */
+/*      NU_INVALID_FUNCTION                 Indicates that expiration    */
+/*                                            function pointer is NULL   */
+/*      NU_INVALID_ENABLE                   Indicates enable parameter   */
+/*                                            is invalid                 */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Changed function interface,                      */
+/*                      resulting in version 1.1                         */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+STATUS  TMSE_Reset_Timer(NU_TIMER *timer_ptr,  
+                VOID (*expiration_routine)(UNSIGNED), 
+                UNSIGNED initial_time, UNSIGNED reschedule_time, OPTION enable)
+{
+
+TM_APP_TCB     *timer;                      /* Timer contorl block ptr  */
+STATUS          status;                     /* Completion status        */
+static char dbgstr[512];
+
+	sprintf(dbgstr, "* TMSE_Reset_Timer(): timer_ptr=%08x, expiration_routine=%08x, initial_time=%x, reschedule_time=%x, enable=%x",
+		(unsigned)timer_ptr, (unsigned)expiration_routine,
+		(unsigned)initial_time, (unsigned)reschedule_time,
+		(unsigned)enable);
+	freecalypso_raw_dbgout(dbgstr);
+
+    /* Move input timer pointer into internal pointer.  */
+    timer =  (TM_APP_TCB *) timer_ptr;
+
+    /* Check the parameters to the reset timer function.  */
+    if (timer == NU_NULL)
+    
+        /* Invalid timer pointer.  */
+        status =  NU_INVALID_TIMER;
+    
+    else if (timer -> tm_id != TM_TIMER_ID) {
+
+	sprintf(dbgstr, "* TMSE_Reset_Timer: invalid tm_id=%08x",
+		(unsigned)timer->tm_id);
+	freecalypso_raw_dbgout(dbgstr);
+
+        /* Invalid timer pointer.  */
+        status =  NU_INVALID_TIMER;
+	}
+    else if (initial_time == 0)
+    
+        /* Invalid time value. */
+        status =  NU_INVALID_OPERATION;
+
+
+    else if (expiration_routine == NU_NULL)
+    
+        /* Invalid expiration function pointer.  */
+        status =  NU_INVALID_FUNCTION;
+        
+    else if ((enable != NU_ENABLE_TIMER) && (enable != NU_DISABLE_TIMER))
+    
+        /* Invalid enable parameter.  */
+        status =  NU_INVALID_ENABLE;
+        
+    else
+
+        /* Call the actual reset timer function.  */
+        status =  TMS_Reset_Timer(timer_ptr, expiration_routine, initial_time,
+                                                   reschedule_time, enable);
+
+	sprintf(dbgstr, "* TMSE_Reset_Timer result: %d", (int)status);
+	freecalypso_raw_dbgout(dbgstr);
+
+    /* Return completion status.  */
+    return(status);
+}
+
+
+/*************************************************************************/
+/*                                                                       */
+/* FUNCTION                                                              */
+/*                                                                       */
+/*      TMSE_Control_Timer                                               */
+/*                                                                       */
+/* DESCRIPTION                                                           */
+/*                                                                       */
+/*      This function performs error checking on the parameters supplied */
+/*      to the control timer function.                                   */
+/*                                                                       */
+/* CALLED BY                                                             */
+/*                                                                       */
+/*      Application                                                      */
+/*                                                                       */
+/* CALLS                                                                 */
+/*                                                                       */
+/*      TMS_Control_Timer                   Actual control timer function*/
+/*                                                                       */
+/* INPUTS                                                                */
+/*                                                                       */
+/*      timer_ptr                           Timer control block pointer  */
+/*      enable                              Disable/enable timer option  */
+/*                                                                       */
+/* OUTPUTS                                                               */
+/*                                                                       */
+/*      NU_INVALID_TIMER                    Indicates the timer pointer  */
+/*                                            is invalid                 */
+/*      NU_INVALID_ENABLE                   Indicates enable parameter   */
+/*                                            is invalid                 */
+/*                                                                       */
+/* HISTORY                                                               */
+/*                                                                       */
+/*         DATE                    REMARKS                               */
+/*                                                                       */
+/*      03-01-1993      Created initial version 1.0                      */
+/*      04-19-1993      Verified version 1.0                             */
+/*      03-01-1994      Changed function interface,                      */
+/*                      resulting in version 1.1                         */
+/*                                                                       */
+/*      03-18-1994      Verified version 1.1                             */
+/*                                                                       */
+/*************************************************************************/
+STATUS  TMSE_Control_Timer(NU_TIMER *timer_ptr, OPTION enable)
+{
+
+TM_APP_TCB     *timer;                      /* Timer control block ptr  */
+STATUS          status;                     /* Completion status        */
+
+
+    /* Move input timer pointer to internal pointer.  */
+    timer =  (TM_APP_TCB *) timer_ptr;
+
+    /* Check the parameters to the reset timer function.  */
+    if (timer == NU_NULL)
+    
+        /* Invalid timer pointer.  */
+        status =  NU_INVALID_TIMER;
+    
+    else if (timer -> tm_id != TM_TIMER_ID)
+    
+        /* Invalid timer pointer.  */
+        status =  NU_INVALID_TIMER;
+
+    else if ((enable != NU_ENABLE_TIMER) && (enable != NU_DISABLE_TIMER))
+    
+        /* Invalid enable parameter.  */
+        status =  NU_INVALID_ENABLE;
+        
+    else
+
+        /* Call actual control timer function.  */
+        status =  TMS_Control_Timer(timer_ptr, enable);
+        
+    /* Return completion status.  */
+    return(status);
+}
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nuc-fw/nucleus/demo/calirq.h	Mon Nov 11 10:17:08 2013 +0000
@@ -0,0 +1,95 @@
+/*
+ * Definitions for Calypso IRQ numbers and the related registers
+ * Added to the FreeNucleus Calypso port by Spacefalcon the Outlaw.
+ *
+ * This header is usable from both .c and .S source files.
+ */
+
+#ifndef _CALYPSO_IRQ_H
+#define _CALYPSO_IRQ_H
+
+#define	IRQ_WATCHDOG		0
+#define	IRQ_TIMER1		1
+#define	IRQ_TIMER2		2
+#define	IRQ_TSP_RX		3
+#define	IRQ_TPU_FRAME		4
+#define	IRQ_TPU_PAGE		5
+#define	IRQ_SIMCARD		6
+#define	IRQ_UART_MODEM		7
+#define	IRQ_KEYPAD_GPIO		8
+#define	IRQ_RTC_TIMER		9
+#define	IRQ_RTC_ALARM_I2C	10
+#define	IRQ_ULPD_GAUGING	11
+#define	IRQ_EXTERNAL		12
+#define	IRQ_SPI			13
+#define	IRQ_DMA			14
+#define	IRQ_API			15
+#define	IRQ_SIM_DETECT		16
+#define	IRQ_EXTERNAL_FIQ	17
+#define	IRQ_UART_IRDA		18
+#define	IRQ_ULPD_GSM_TIMER	19
+#define	IRQ_GEA			20
+
+#define	MAX_IRQ_NUM		20
+
+#define	INTH_BASE_ADDR		0xFFFFFA00
+
+#ifdef __ASSEMBLER__
+
+/*
+ * Assembly source with cpp
+ *
+ * The most convenient way to access registers like these from ARM
+ * assembly is to load the base address of the register block in some
+ * ARM register, using only one ldr rN, =xxx instruction and only one
+ * literal pool entry, and then access various registers in the block
+ * from the same base using the immediate offset addressing mode.
+ *
+ * Here we define the offsets for the usage scenario above.
+ */
+
+#define	IT_REG1		0x00
+#define	IT_REG2		0x02
+#define	MASK_IT_REG1	0x08
+#define	MASK_IT_REG2	0x0A
+#define	IRQ_NUM		0x10
+#define	FIQ_NUM		0x12
+#define	IRQ_CTRL	0x14
+#define	ILR_OFFSET	0x20
+
+#else
+
+/*
+ * C source
+ *
+ * For access from C, we define the layout of the INTH register block
+ * as a struct, and then define a pleudo-global-var for easy "volatile"
+ * access.
+ */
+
+struct inth_regs {
+	unsigned short	it_reg1;
+	unsigned short	it_reg2;
+	unsigned short	pad1[2];
+	unsigned short	mask_it_reg1;
+	unsigned short	mask_it_reg2;
+	unsigned short	pad2[2];
+	unsigned short	irq_num;
+	unsigned short	fiq_num;
+	unsigned short	irq_ctrl;
+	unsigned short	pad3[5];
+	unsigned short	ilr_irq[MAX_IRQ_NUM+1];
+};
+
+#define	INTH_REGS	(*(volatile struct inth_regs *) INTH_BASE_ADDR)
+
+/*
+ * C code can now access INTH registers like this:
+ *
+ * old_mask = INTH_REGS.mask_it_reg1;
+ * INTH_REGS.mask_it_reg1 = new_mask;
+ */
+
+#endif
+
+#endif /* _CALYPSO_IRQ_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nuc-fw/nucleus/demo/caltimer.h	Mon Nov 11 10:17:08 2013 +0000
@@ -0,0 +1,59 @@
+/*
+ * Definitions for Calypso general-purpose timer registers
+ * Added to the FreeNucleus Calypso port by Spacefalcon the Outlaw.
+ *
+ * This header is usable from both .c and .S source files.
+ */
+
+#ifndef _CALYPSO_TIMER_H
+#define _CALYPSO_TIMER_H
+
+#define	TIMER1_BASE_ADDR	0xFFFE3800
+#define	TIMER2_BASE_ADDR	0xFFFE6800
+
+#ifdef __ASSEMBLER__
+
+/*
+ * Assembly source with cpp
+ *
+ * The most convenient way to access registers like these from ARM
+ * assembly is to load the base address of the register block in some
+ * ARM register, using only one ldr rN, =xxx instruction and only one
+ * literal pool entry, and then access various registers in the block
+ * from the same base using the immediate offset addressing mode.
+ *
+ * Here we define the offsets for the usage scenario above.
+ */
+
+#define	CNTL_TIM	0x00
+#define	LOAD_TIM	0x02
+#define	READ_TIM	0x04
+
+#else
+
+/*
+ * C source
+ *
+ * For access from C, we define the layout of each timer register block
+ * as a struct, and then define a pleudo-global-var for easy "volatile"
+ * access to each of the 2 timers.
+ */
+
+struct timer_regs {
+	unsigned char	cntl;
+	unsigned char	pad;
+	unsigned short	load;
+	unsigned short	read;
+};
+
+#define	TIMER1_REGS	(*(volatile struct timer_regs *) TIMER1_BASE_ADDR)
+#define	TIMER2_REGS	(*(volatile struct timer_regs *) TIMER2_BASE_ADDR)
+
+#endif
+
+/* CNTL register bit definitions */
+#define	CNTL_START		0x01
+#define	CNTL_AUTO_RELOAD	0x02
+#define	CNTL_CLOCK_ENABLE	0x20
+
+#endif /* include guard */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nuc-fw/nucleus/demo/demo.c	Mon Nov 11 10:17:08 2013 +0000
@@ -0,0 +1,530 @@
+/* Include Nucleus C-Library file */
+//#include "ncl\inc\nu_ncl.h"
+
+/* Include necessary Nucleus PLUS files.  */
+#include "nucleus.h"
+
+/* Define serial output/input functionality. To disable serial I/O,
+   replace NU_TRUE with NU_FALSE */
+
+#define NU_SERIAL_OUTPUT  NU_TRUE
+#define NU_SERIAL_INPUT   NU_TRUE
+
+#if (NU_SERIAL_OUTPUT)
+#include "nu_sd.h"            /* Nucleus Serial Driver interface */
+#endif
+
+/* Define Application data structures.  */
+
+NU_TASK         Task_0;
+NU_TASK         Task_1;
+NU_TASK         Task_2;
+NU_TASK         Task_3;
+NU_TASK         Task_4;
+NU_TASK         Task_5;
+NU_QUEUE        Queue_0;
+NU_SEMAPHORE    Semaphore_0;
+NU_EVENT_GROUP  Event_Group_0;
+NU_MEMORY_POOL  System_Memory;
+
+
+/* Allocate global counters. */
+UNSIGNED  Task_Time;
+UNSIGNED  Task_2_messages_received;
+UNSIGNED  Task_2_invalid_messages;
+UNSIGNED  Task_1_messages_sent;
+NU_TASK  *Who_has_the_resource;
+UNSIGNED  Event_Detections;
+
+#if (NU_SERIAL_OUTPUT)
+NU_SERIAL_PORT  port;
+#endif
+
+#ifdef NU_FIQ_DEMO
+UINT32 FIQ_Count;
+#endif
+
+extern  UNSIGNED TMD_System_Clock;
+
+/* Define prototypes for function references.  */
+VOID    task_0(UNSIGNED argc, VOID *argv);
+VOID    task_1(UNSIGNED argc, VOID *argv);
+VOID    task_2(UNSIGNED argc, VOID *argv);
+VOID    task_3_and_4(UNSIGNED argc, VOID *argv);
+VOID    task_5(UNSIGNED argc, VOID *argv);
+CHAR    buffer[12]; /* temp buffer for Itoa conversion */
+INT     n; /* strlen */
+
+
+
+/* Define the Application_Initialize routine that determines the initial
+   Nucleus PLUS application environment.  */
+
+void    Application_Initialize(void *first_available_memory)
+{
+
+VOID           *pointer;
+STATUS         status;
+
+    /* Create a system memory pool that will be used to allocate task stacks,
+       queue areas, etc.  */
+    status = NU_Create_Memory_Pool(&System_Memory, "SYSMEM",
+                        first_available_memory, 25000, 50, NU_FIFO);
+    if (status != NU_SUCCESS)
+    {
+        ERC_System_Error(status);
+    }
+
+    /* Create each task in the system.  */
+
+    /* Create task 0.  */
+    NU_Allocate_Memory(&System_Memory, &pointer, 2000, NU_NO_SUSPEND);
+    status = NU_Create_Task(&Task_0, "TASK 0", task_0, 0, NU_NULL, pointer, 2000, 1, 20,
+                                                      NU_PREEMPT, NU_START);
+    if (status != NU_SUCCESS)
+    {
+        ERC_System_Error(status);
+    }
+
+    /* Create task 1.  */
+    NU_Allocate_Memory(&System_Memory, &pointer, 2000, NU_NO_SUSPEND);
+    status = NU_Create_Task(&Task_1, "TASK 1", task_1, 0, NU_NULL, pointer, 2000, 10, 5,
+                                                      NU_PREEMPT, NU_START);
+    if (status != NU_SUCCESS)
+    {
+        ERC_System_Error(status);
+    }
+
+    /* Create task 2.  */
+    NU_Allocate_Memory(&System_Memory, &pointer, 2000, NU_NO_SUSPEND);
+    status = NU_Create_Task(&Task_2, "TASK 2", task_2, 0, NU_NULL, pointer, 2000, 10, 5,
+                                                      NU_PREEMPT, NU_START);
+    if (status != NU_SUCCESS)
+    {
+        ERC_System_Error(status);
+    }
+
+    /* Create task 3.  Note that task 4 uses the same instruction area.  */
+    NU_Allocate_Memory(&System_Memory, &pointer, 2000, NU_NO_SUSPEND);
+    status = NU_Create_Task(&Task_3, "TASK 3", task_3_and_4, 0, NU_NULL, pointer,
+                                        2000, 5, 0, NU_PREEMPT, NU_START);
+    if (status != NU_SUCCESS)
+    {
+        ERC_System_Error(status);
+    }
+
+    /* Create task 4.  Note that task 3 uses the same instruction area.  */
+    NU_Allocate_Memory(&System_Memory, &pointer, 2000, NU_NO_SUSPEND);
+    status = NU_Create_Task(&Task_4, "TASK 4", task_3_and_4, 0, NU_NULL, pointer,
+                                        2000, 5, 0, NU_PREEMPT, NU_START);
+    if (status != NU_SUCCESS)
+    {
+        ERC_System_Error(status);
+    }
+
+    /* Create task 5.  */
+    NU_Allocate_Memory(&System_Memory, &pointer, 2000, NU_NO_SUSPEND);
+    status = NU_Create_Task(&Task_5, "TASK 5", task_5, 0, NU_NULL, pointer, 2000, 7, 0,
+                                                      NU_PREEMPT, NU_START);
+    if (status != NU_SUCCESS)
+    {
+        ERC_System_Error(status);
+    }
+
+
+    /* Create communication queue.  */
+    NU_Allocate_Memory(&System_Memory, &pointer, 100*sizeof(UNSIGNED),
+                                                        NU_NO_SUSPEND);
+    status = NU_Create_Queue(&Queue_0, "QUEUE 0", pointer, 100, NU_FIXED_SIZE, 1,
+                                                                      NU_FIFO);
+    if (status != NU_SUCCESS)
+    {
+        ERC_System_Error(status);
+    }
+
+    /* Create synchronization semaphore.  */
+    status = NU_Create_Semaphore(&Semaphore_0, "SEM 0", 1, NU_FIFO);
+    if (status != NU_SUCCESS)
+    {
+        ERC_System_Error(status);
+    }
+
+    /* Create event flag group.  */
+    status = NU_Create_Event_Group(&Event_Group_0, "EVGROUP0");
+    if (status != NU_SUCCESS)
+    {
+        ERC_System_Error(status);
+    }
+
+
+}
+
+/* Define the system timer task.  More complicated systems might use a
+   routine like this to perform periodic message sending and other time
+   oriented functions.  */
+
+
+void   task_0(UNSIGNED argc, VOID *argv)
+{
+
+STATUS          status;
+
+
+#if (NU_SERIAL_OUTPUT)
+CHAR            msg[40];
+INT             i;
+
+CHAR            ch;
+#endif /* NU_SERIAL_OUTPUT */
+
+
+#if (NU_SERIAL_OUTPUT)
+    /* Init the serial port. */
+    port.com_port   = DEFAULT_UART_PORT;
+    port.baud_rate  = DEFAULT_UART_BAUD;
+    port.data_bits  = DEFAULT_UART_DATA;
+    port.stop_bits  = DEFAULT_UART_STOP;
+    port.parity     = DEFAULT_UART_PARITY;
+    port.data_mode  = DEFAULT_UART_MODE;
+    port.communication_mode = SERIAL_MODE;
+    port.sd_buffer_size   =   DEFAULT_UART_BUFFER;
+
+    status = NU_SD_Init_Port (&port);
+    if (status != NU_SUCCESS)
+    {
+        ERC_System_Error(status);
+    }
+
+#endif /* NU_SERIAL_OUTPUT */
+
+
+    /* Access argc and argv just to avoid compilation warnings.  */
+    status =  (STATUS) argc + (STATUS) argv;
+
+    /* Set the clock to 0.  This clock ticks every 18 system timer ticks. */
+    Task_Time =  0;
+
+        while(1)
+        {
+
+            /* Sleep for 100 timer ticks.  The value of the tick is programmable
+               in INT.S and is relative to the speed of the target system.  */
+            NU_Sleep(100);
+
+#if (NU_SERIAL_OUTPUT)
+            NU_SD_Put_String("\n\r****************************************", &port);
+            NU_SD_Put_String("***************************************\n\r", &port);
+            NU_SD_Put_String(NU_Release_Information(), &port);
+            NU_SD_Put_String("\n\r", &port);
+
+            NU_SD_Put_String("****************************************", &port);
+            NU_SD_Put_String("***************************************\n\n\r", &port);
+            NU_SD_Put_String("System Variable Status: \n\n\r", &port);
+
+            strcpy(msg, "Task 0 time:                      ");
+	    sprintf(buffer, "%lu", Task_Time);
+            n = strlen(buffer);
+            if (n>=8)
+            {
+                strcat(msg, buffer);
+                strcat(msg, "\n\r");
+            }
+            else
+            {
+                for (i=0;i<(8-n);i++)
+                    strcat(msg, " ");
+                strcat(msg, buffer);
+                strcat(msg, "\n\r");
+            }
+
+            NU_SD_Put_String(msg, &port);
+
+            strcpy(msg, "Event detections:                 ");
+	    sprintf(buffer, "%lu", Event_Detections);
+            n = strlen(buffer);
+            if (n>=8)
+            {
+                strcat(msg, buffer);
+                strcat(msg, "\n\n\n\r");
+            }
+            else
+            {
+                for (i=0;i<(8-n);i++)
+                    strcat(msg, " ");
+                strcat(msg, buffer);
+                strcat(msg, "\n\n\n\r");
+            }
+
+            NU_SD_Put_String(msg, &port);
+
+            strcpy(msg, "Task 1 messages sent:             ");
+	    sprintf(buffer, "%lu", Task_1_messages_sent);
+            n = strlen(buffer);
+            if (n>=8)
+            {
+                strcat(msg, buffer);
+                strcat(msg, "\n\r");
+            }
+            else
+            {
+                for (i=0;i<(8-n);i++)
+                    strcat(msg, " ");
+                strcat(msg, buffer);
+                strcat(msg, "\n\r");
+            }
+
+            NU_SD_Put_String(msg, &port);
+
+            strcpy(msg, "Task 2 messages received:         ");
+	    sprintf(buffer, "%lu", Task_2_messages_received);
+            n = strlen(buffer);
+            if (n>=8)
+            {
+                strcat(msg, buffer);
+                strcat(msg, "\n\n\r");
+            }
+            else
+            {
+                for (i=0;i<(8-n);i++)
+                    strcat(msg, " ");
+                strcat(msg, buffer);
+                strcat(msg, "\n\n\r");
+            }
+
+            NU_SD_Put_String(msg, &port);
+
+            strcpy(msg, "Task 2 invalid messages:          ");
+	    sprintf(buffer, "%lu", Task_2_invalid_messages);
+            n = strlen(buffer);
+            if (n>=8)
+            {
+                strcat(msg, buffer);
+                strcat(msg, "\n\n\r");
+            }
+            else
+            {
+                for (i=0;i<(8-n);i++)
+                    strcat(msg, " ");
+                strcat(msg, buffer);
+                strcat(msg, "\n\n\r");
+            }
+
+            NU_SD_Put_String(msg, &port);
+
+            if (Who_has_the_resource == &Task_3)
+               NU_SD_Put_String("Who has the resource:               Task 3", &port);
+            else if (Who_has_the_resource == &Task_4)
+               NU_SD_Put_String("Who has the resource:               Task 4", &port);
+            else
+               NU_SD_Put_String("Who has the resource:               Nobody", &port);
+            NU_SD_Put_String("\n\n\n\r", &port);
+
+            strcpy(msg, "Timer Interrupts:                 ");
+	    sprintf(buffer, "%lu", TMD_System_Clock);
+            n = strlen(buffer);
+            if (n>=8)
+            {
+                strcat(msg, buffer);
+                strcat(msg, "\n\n\r");
+            }
+            else
+            {
+                for (i=0;i<(8-n);i++)
+                    strcat(msg, " ");
+                strcat(msg, buffer);
+                strcat(msg, "\n\n\r");
+            }
+
+            NU_SD_Put_String(msg, &port);
+
+            NU_SD_Put_String("Buffer:  ", &port);
+
+#if (NU_SERIAL_INPUT)
+            while (NU_SD_Data_Ready(&port))
+            {
+                ch = NU_SD_Get_Char(&port);
+                NU_SD_Put_Char(ch, &port);
+            }
+#endif /* NU_SERIAL_INPUT */
+
+
+            NU_SD_Put_String("\n\n\r", &port);
+
+
+#endif /* NU_SERIAL_OUTPUT */
+            /* Increment the time.  */
+            Task_Time++;
+
+            /* Set an event flag to lift the suspension on task 5.  */
+            status =  NU_Set_Events(&Event_Group_0, 1, NU_OR);
+
+        }
+
+}
+
+
+/* Define the queue sending task.  Note that the only things that cause
+   this task to suspend are queue full conditions and the time slice
+   specified in the configuration file.  */
+
+void   task_1(UNSIGNED argc, VOID *argv)
+{
+
+STATUS         status;
+UNSIGNED       Send_Message;
+
+    /* Access argc and argv just to avoid compilation warnings.  */
+    status =  (STATUS) argc + (STATUS) argv;
+
+    /* Initialize the message counter.  */
+    Task_1_messages_sent =  0;
+
+    /* Initialize the message contents.  The receiver will examine the
+       message contents for errors.  */
+    Send_Message = 0;
+
+    while(1)
+    {
+    
+         /* Send the message to Queue_0, which task 2 reads from.  Note
+            that if the destination queue fills up this task suspends until
+            room becomes available.  */
+         status =  NU_Send_To_Queue(&Queue_0, &Send_Message, 1, NU_SUSPEND);
+         
+         /* Determine if the message was sent successfully.  */
+         if (status == NU_SUCCESS)
+             Task_1_messages_sent++;
+             
+         /* Modify the contents of the next message to send.  */
+         Send_Message++;
+    }
+}
+
+
+/* Define the queue receiving task.  Note that the only things that cause
+   this task to suspend are queue empty conditions and the time slice
+   specified in the configuration file.   */
+
+void   task_2(UNSIGNED argc, VOID *argv)
+{
+
+STATUS         status; 
+UNSIGNED       Receive_Message;
+UNSIGNED       received_size;
+UNSIGNED       message_expected;
+
+    /* Access argc and argv just to avoid compilation warnings.  */
+    status =  (STATUS) argc + (STATUS) argv;
+
+    /* Initialize the message counter.  */
+    Task_2_messages_received =  0;
+
+    /* Initialize the message error counter.  */
+    Task_2_invalid_messages =  0;
+
+    /* Initialize the message contents to expect.  */
+    message_expected =  0;
+    
+    while(1)
+    {
+    
+         /* Retrieve a message from Queue_0, which task 1 writes to.  Note
+            that if the source queue is empty this task suspends until
+            something becomes available.  */
+         status =  NU_Receive_From_Queue(&Queue_0, &Receive_Message, 1, 
+                                &received_size, NU_SUSPEND);
+         
+         /* Determine if the message was received successfully.  */
+         if (status == NU_SUCCESS)
+             Task_2_messages_received++;
+             
+         /* Check the contents of the message against what this task
+            is expecting.  */
+         if ((received_size != 1) ||
+             (Receive_Message != message_expected))
+             Task_2_invalid_messages++;
+         
+         /* Modify the expected contents of the next message.  */
+         message_expected++;
+    }
+}
+
+
+/* Tasks 3 and 4 want a single resource.  Once one of the tasks gets the
+   resource, it keeps it for 100 clock ticks before releasing it.  During
+   this time the other task suspends waiting for the resource.  Note that
+   both task 3 and 4 use the same instruction areas but have different 
+   stacks.  */
+   
+void  task_3_and_4(UNSIGNED argc, VOID *argv)
+{
+
+STATUS  status;
+
+    /* Access argc and argv just to avoid compilation warnings.  */
+    status =  (STATUS) argc + (STATUS) argv;
+
+    /* Loop to allocate and deallocate the resource.  */
+    while(1)
+    {
+    
+         /* Allocate the resource.  Suspend until it becomes available.  */
+         status =  NU_Obtain_Semaphore(&Semaphore_0, NU_SUSPEND);
+         
+         /* If the status is successful, show that this task owns the 
+            resource.  */
+         if (status ==  NU_SUCCESS)
+         {
+         
+             Who_has_the_resource =  NU_Current_Task_Pointer();
+             
+             /* Sleep for 100 ticks to cause the other task to suspend on 
+                the resource.  */
+             NU_Sleep(100);
+             
+             /* Release the semaphore.  */
+             NU_Release_Semaphore(&Semaphore_0);
+        }
+    }
+}
+
+
+/* Define the task that waits for the event to be set by task 0.  */
+
+void  task_5(UNSIGNED argc, VOID *argv)
+{
+
+STATUS          status;
+UNSIGNED        event_group;
+
+    /* Access argc and argv just to avoid compilation warnings.  */
+    status =  (STATUS) argc + (STATUS) argv;
+
+    /* Initialize the event detection counter.  */
+    Event_Detections =  0;
+
+    /* Continue this process forever.  */
+    while(1)
+    {
+        /* Wait for an event and consume it.  */
+        status =  NU_Retrieve_Events(&Event_Group_0, 1, NU_OR_CONSUME,
+                                     &event_group, NU_SUSPEND);
+
+        /* If the status is okay, increment the counter.  */
+        if (status == NU_SUCCESS)
+        {
+          Event_Detections++;
+
+        }
+    }
+}
+
+
+#ifdef NU_FIQ_DEMO
+void FIQ_LISR(VOID)
+{
+    FIQ_Count++;
+}
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nuc-fw/nucleus/demo/irqshell.S	Mon Nov 11 10:17:08 2013 +0000
@@ -0,0 +1,584 @@
+/*
+ * FreeNucleus Calypso port by Michael Spacefalcon
+ *
+ * This assembly module contains IRQ handler shell
+ * and some closely related support functions.
+ *
+ * The approach to IRQ handling implemented in the present version
+ * is exactly the same as was found in XVilka's original nucleus_plus.tar.gz
+ * code targeting OMAP1510.  I personally consider it very dumb and
+ * suboptimal, but the present version is merely a proof of concept -
+ * changing as little as possible from our starting point will (hopefully)
+ * make it easier to get this code to compile, link and maybe even run.
+ */
+
+#include "asm_defs.h"
+#include "calirq.h"
+
+	.code 32
+
+/*
+ **********************************
+ * GLOBAL VARIABLE DECLARATIONS   *
+ **********************************
+ */
+
+	.data
+
+@ Define vector table used by INT_IRQ to branch to necessary ISR
+
+	.globl	INT_IRQ_Vectors
+INT_IRQ_Vectors:
+    .word     INT_Interrupt_Shell             @ Vector 0
+    .word     INT_Interrupt_Shell             @ Vector 1
+    .word     INT_Timer_Interrupt             @ Vector 2 - TIMER2
+    .word     INT_Interrupt_Shell             @ Vector 3
+    .word     INT_Interrupt_Shell             @ Vector 4
+    .word     INT_Interrupt_Shell             @ Vector 5
+    .word     INT_Interrupt_Shell             @ Vector 6
+    .word     INT_Interrupt_Shell             @ Vector 7
+    .word     INT_Interrupt_Shell             @ Vector 8
+    .word     INT_Interrupt_Shell             @ Vector 9
+    .word     INT_Interrupt_Shell             @ Vector 10
+    .word     INT_Interrupt_Shell             @ Vector 11
+    .word     INT_Interrupt_Shell             @ Vector 12
+    .word     INT_Interrupt_Shell             @ Vector 13
+    .word     INT_Interrupt_Shell             @ Vector 14
+    .word     INT_Interrupt_Shell             @ Vector 15
+    .word     INT_Interrupt_Shell             @ Vector 16
+    .word     INT_Interrupt_Shell             @ Vector 17
+    .word     INT_Interrupt_Shell             @ Vector 18
+    .word     INT_Interrupt_Shell             @ Vector 19
+    .word     INT_Interrupt_Shell             @ Vector 20
+
+@ Define the order in which the interrupts will be executed by software(INT_IRQ)
+@ Level 1 Interrupt Handler
+	.globl	INT_IRQ_Priority
+INT_IRQ_Priority:
+	.word	0
+	.word	1
+	.word	2
+	.word	3
+	.word	4
+	.word	5
+	.word	6
+	.word	7
+	.word	8
+	.word	9
+	.word	10
+	.word	11
+	.word	12
+	.word	13
+	.word	14
+	.word	15
+	.word	16
+	.word	17
+	.word	18
+	.word	19
+	.word	20
+INT_Priority_End:
+
+	.text
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      INT_Setup_Vector                                                 
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function sets up the specified vector with the new vector   
+ *      value.  The previous vector value is returned to the caller.     
+ *                                                                       
+ *                                                                       
+ *      Major Revision:                                                  
+ *                                                                       
+ *          M. Kyle Craig, Accelerated Technology, Inc.                  
+ *                                                                       
+ *                                                                       
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      Application                                                      
+ *      TCC_Register_LISR                   Register LISR for vector     
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      vector                              Vector number to setup       
+ *      new                                 Pointer to new assembly      
+ *                                            language ISR               
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      old vector contents                                              
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        08-27-1994      Created initial version 1.0      
+ *      D. Lamie        08-27-1994      Verified version 1.0             
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID  *INT_Setup_Vector(INT vector, VOID *new)
+@{
+
+	.globl  INT_Setup_Vector
+INT_Setup_Vector:
+
+@VOID    *old_vector;                        /* Old interrupt vector      */
+@VOID   **vector_table;                      /* Pointer to vector table   */
+
+@ Calculate the starting address of the actual vector table.
+@    vector_table =  (VOID **) 0;
+
+@ Pickup the old interrupt vector.
+@    old_vector =  vector_table[vector];
+@    
+@ Setup the new interrupt vector.
+@    vector_table[vector] =  new;
+@    
+@ Return the old interrupt vector.
+@    return(old_vector);
+
+
+        LDR     r2, =INT_IRQ_Vectors        @ Load the vector table address
+        MOV     r0, r0, LSL #2              @ Multiply vector by 4 to get offset into table
+        LDR     r3, [r2,r0]                 @ Load the old pointer
+        STR     r1, [r2,r0]                 @ Store the new pointer into the vector table
+
+        MOV     r0, r3                      @ Put the old pointer into the return register
+
+        BX      lr                          @ Return to caller
+
+@}
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      INT_Retrieve_Shell                                               
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This function retrieves the pointer to the shell interrupt       
+ *      service routine.  The shell interrupt service routine calls      
+ *      the LISR dispatch routine.                                       
+ *                                                                       
+ *                                                                       
+ *      Major Revision:                                                  
+ *                                                                       
+ *          M. Kyle Craig, Accelerated Technology, Inc.                  
+ *                                                                       
+ *                                                                       
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      TCC_Register_LISR                   Register LISR for vector     
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      vector                              Vector number to setup       
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      shell pointer                                                    
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      W. Lamie        08-27-1994      Created initial version 1.0      
+ *      D. Lamie        08-27-1994      Verified version 1.0             
+ *                                                                       
+ ************************************************************************
+ */
+
+@VOID  *INT_Retrieve_Shell(INT vector)
+@{
+
+	.globl  INT_Retrieve_Shell
+INT_Retrieve_Shell:
+
+    @ Return the LISR Shell interrupt routine.
+    @ return(INT_Vectors[vector]);
+
+        LDR     r1, =INT_IRQ_Vectors        @ Load the vector table address
+        MOV     r0, r0, LSL #2              @ Multiply vector by 4 to get offset into table
+        LDR     r0, [r1,r0]                 @ Load interrupt handler pointer into return register
+                           
+        BX      lr                          @ Return to caller
+
+     
+@}
+
+/*
+ ************************************************************************
+ *
+ * FUNCTION
+ *
+ *      _INT_IRQ
+ *
+ * DESCRIPTION
+ *
+ *      This routine is the board-specific section for
+ *      level 1 interrupt handling
+ *
+ * CALLED BY                                                             
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      TMT_Timer_Interrupt                                              
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      B. Ronquillo      05-10-00        Created initial version 1.0      
+ *                                                                       
+ ************************************************************************
+ */
+
+	.globl  _INT_IRQ
+_INT_IRQ:
+
+    STMDB   sp!,{r0-r4}                     @ Save r0-r4 on temporary IRQ stack
+    SUB     lr,lr,#4                        @ Adjust IRQ return address
+
+/*
+ ********************************
+ * Begin Hardware Specific Code *
+ ********************************
+ */
+
+    LDR     r3, =INTH_BASE_ADDR             @ load Interrupt Control Base
+    @ Get enable register value
+    @ original instr was: LDR     r4, [r3,#INT_CNTRL_MIR]
+    @ but on the Calypso we have to read two 16-bit regs
+    ldrh    r0, [r3, #MASK_IT_REG1]
+    ldrh    r1, [r3, #MASK_IT_REG2]
+    @ now combine them into a 32-bit word in r4 for the old code to work as-is
+    orr     r4, r0, r1, lsl #16
+
+/*
+ ******************************
+ * End Hardware Specific Code *  
+ ******************************
+ */
+
+    STMDB   sp!,{r4}                        @ Put the enable register value on the IRQ stack
+    MVN     r4,#0                           @ Start with 0xFFFFFFFF to allow nesting of interrupts
+
+/*
+ ********************************
+ * Begin Hardware Specific Code *
+ ********************************
+ */
+
+    @ Read Pending reg
+    @ original instr was: LDR     r2, [r3,#INT_CNTRL_ITR]
+    @ do the same trick as we did for the mask regs
+    ldrh    r0, [r3, #IT_REG1]
+    ldrh    r1, [r3, #IT_REG2]
+    orr     r2, r0, r1, lsl #16
+
+/*
+ ******************************
+ * End Hardware Specific Code *
+ ******************************
+ */
+
+    LDR     r3, =INT_IRQ_Priority           @ Get the Priority table address
+
+IRQ_VECTOR_LOOP:
+    LDR     r0, [r3,#0]                     @ Load first vector to be checked from priority table
+    MOV     r1, #1                          @ Build mask
+    MOV     r1, r1, LSL r0                  @ Use vector number to set mask to correct bit position
+    TST     r1, r2                          @ Test if pending bit is set
+    BNE     IRQ_VECTOR_FOUND                @ If bit is set, branch to found section...
+
+    BIC     r4,r4,r1                        @ Clear mask bit to keep higher priority ints active
+    ADD     r3, r3, #4                      @ Move to next word in the priority table
+    LDR     r0, =INT_Priority_End           @ Load the end address for the priority table
+    CMP     r0, r3                          @ Make sure not at the end of the table (shouldn't happen!)
+    BNE     IRQ_VECTOR_LOOP                 @ Continue to loop if not at the end of the table
+
+    @ No bits in pending register set, restore registers and exit interrupt servicing
+    ADD     sp,sp,#4                        @ Adjust sp above IRQ enable value
+    LDMIA   sp!,{r0-r4}                     @ Restore r0-r4
+    STMDB   sp!,{lr}                        @ Put return address for IRQ on stack
+    LDMIA   sp!,{pc}^                       @ return to the point of the exception and restore SPSR
+ 
+IRQ_VECTOR_FOUND:
+
+/*
+ ********************************
+ * Begin Hardware Specific Code *
+ ********************************
+ */
+
+    LDR     r3, =INTH_BASE_ADDR             @ load Interrupt Control Base
+
+    MVN     r2, r1                          @ Get the inverse of the interrupt vector
+    @ Write a zero to the interrupt being handled (IT_REGn)
+    cmp     r0, #16
+    strloh  r2, [r3, #IT_REG1]
+    mov     r2, r2, lsr #16
+    strhsh  r2, [r3, #IT_REG2]
+
+    @ Read the Mask reg - just like we did before
+    ldrh    r1, [r3, #MASK_IT_REG1]
+    ldrh    r2, [r3, #MASK_IT_REG2]
+    orr     r2, r1, r2, lsl #16
+    @ was LDR     r2, [r3,#INT_CNTRL_MIR]
+
+    ORR     r4, r2, r4                      @ Turn off lower priority pending bits and currently masked bits
+
+    @ write both mask registers
+    @ was STR     r4, [r3,#INT_CNTRL_MIR]
+    strh    r4, [r3, #MASK_IT_REG1]
+    mov     r1, r4, lsr #16
+    strh    r1, [r3, #MASK_IT_REG2]
+
+    MOV     r1, #1                          @ Clear the pending interrupt 
+    STRH    r1, [r3,#IRQ_CTRL]              @ by writing a 1 to the Control Reg
+
+/*
+ ******************************
+ * End Hardware Specific Code *
+ ******************************
+ */
+
+    LDR     r3, =INT_IRQ_Vectors            @ Get IRQ vector table address
+    MOV     r2, r0, LSL #2                  @ Multiply vector by 4 to get offset into table
+    ADD     r3, r3, r2                      @ Adjust vector table address to correct offset
+    LDR     r2, [r3,#0]                     @ Load branch address from vector table
+
+    MOV     PC, r2                          @ Jump to correct branch location based on vector table
+
+@ END: INT_IRQ
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                         
+ *     INT_Interrupt_Shell                                               
+ *                                                                         
+ * DESCRIPTION                                                           
+ *                                                                         
+ *     Handles all interrupts which use NU_Register_LISR.                
+ *                                                                         
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      INT_IRQ                                                          
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      TCT_Dispatch_LISR                                                
+ *      TCT_Interrupt_Context_Restore                                    
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      vector (register r0)                                             
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None                                  
+ ************************************************************************
+ */
+
+    .globl INT_Interrupt_Shell
+INT_Interrupt_Shell:
+
+    MOV     r4,lr                           @ Put IRQ return address into r4
+
+    BL      TCT_Interrupt_Context_Save
+
+    BL      TCC_Dispatch_LISR
+
+    MRS     r1,CPSR                         @ Pickup current CPSR
+    BIC     r1,r1,#MODE_MASK                @ Clear the mode bits
+    ORR     r1,r1,#(IRQ_MODE_OR_LOCKOUT)    @ Set the IRQ mode bits and Lockout interrupts
+    MSR     CPSR,r1                         @ Lockout interrupts/change to IRQ mode
+
+/*
+ ********************************
+ * Begin Hardware Specific Code *
+ ********************************
+ */
+    LDMIA   sp!,{r1}                        @ Get IRQ enable value off IRQ stack
+
+    LDR     r2, =INTH_BASE_ADDR             @ Get IRQ0 base register address
+    @ write it into both mask regs
+    @was STR     r1,[r2,#INT_CNTRL_MIR]
+    strh    r1, [r2, #MASK_IT_REG1]
+    mov     r1, r1, lsr #16
+    strh    r1, [r2, #MASK_IT_REG2]
+/*
+ ******************************
+ * End Hardware Specific Code *                                         
+ ******************************
+ */
+    
+    MRS     r1,CPSR                         @ Pickup current CPSR
+    BIC     r1,r1,#MODE_MASK                @ Clear the mode bits
+    ORR     r1,r1,#SUP_MODE                 @ Set the SVC mode bits
+    MSR     CPSR,r1                         @ Change to SVC mode
+
+    B       TCT_Interrupt_Context_Restore
+
+/*
+ ************************************************************************
+ *                                                                       
+ * FUNCTION                                                              
+ *                                                                       
+ *      INT_Timer_Interrupt                                              
+ *                                                                       
+ * DESCRIPTION                                                           
+ *                                                                       
+ *      This routine is the board-specific section of the timer          
+ *      interrupt handling                                               
+ *                                                                       
+ * CALLED BY                                                             
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * CALLS                                                                 
+ *                                                                       
+ *      TMT_Timer_Interrupt                                              
+ *                                                                       
+ * INPUTS                                                                
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ *                                                                       
+ * OUTPUTS                                                               
+ *                                                                       
+ *      None                                                             
+ *                                                                       
+ * HISTORY                                                               
+ *                                                                       
+ *         NAME            DATE                    REMARKS               
+ *                                                                       
+ *      B.Ronquillo        05-10-00          Created initial version 1.0   
+ *                                                                       
+ ************************************************************************
+ */
+
+	.globl  INT_Timer_Interrupt
+INT_Timer_Interrupt:
+
+/*
+ ********************************
+ * Begin Hardware Specific Code *
+ ********************************
+ * Clear the pending timer interrupt
+ *
+ * This is done in the INT_IRQ function by writing a zero to the   
+ * timer bit.
+ *
+ ******************************
+ * End Hardware Specific Code *
+ ******************************
+ */
+
+    MOV     r4,lr                           @ Put IRQ return address into r4
+
+    BL      TCT_Interrupt_Context_Save
+
+    BL      TMT_Timer_Interrupt             @ Call the timer interrupt
+                                            @ processing.
+
+    MRS     r1,CPSR                         @ Pickup current CPSR
+    BIC     r1,r1,#MODE_MASK                @ Clear the mode bits
+    ORR     r1,r1,#IRQ_MODE                 @ Set the IRQ mode bits
+    MSR     CPSR,r1                         @ Change to IRQ mode
+
+/*
+ ********************************
+ * Begin Hardware Specific Code *
+ ********************************
+ */
+    LDMIA   sp!,{r1}                        @ Get IRQ enable value off IRQ stack
+
+    LDR     r2, =INTH_BASE_ADDR             @ Get IRQ0 base register address
+    @ write it into both mask regs
+    @was STR     r1,[r2,#INT_CNTRL_MIR]
+    strh    r1, [r2, #MASK_IT_REG1]
+    mov     r1, r1, lsr #16
+    strh    r1, [r2, #MASK_IT_REG2]
+/*
+ ******************************
+ * End Hardware Specific Code *                                         
+ ******************************
+ */
+
+    MRS     r1,CPSR                         @ Pickup current CPSR
+    BIC     r1,r1,#MODE_MASK                @ Clear the mode bits
+    ORR     r1,r1,#SUP_MODE                 @ Set the SVC mode bits
+    MSR     CPSR,r1                         @ Change to SVC mode
+
+    B       TCT_Interrupt_Context_Restore
+
+@}
+@ End of INT_Timer_Interrupt
+
+/*
+ * INT_Interrupt_Init function written by Michael Spacefalcon
+ * for the FreeNucleus Calypso port - takes the place of
+ * INT_Install_Vector_Table, called from INT_Initialize.
+ */
+
+	.globl	INT_Interrupt_Init
+INT_Interrupt_Init:
+
+@ first mask all interrupts in the INTH
+
+	ldr	r0, =INTH_BASE_ADDR
+	mvn	r1, #0
+	strh	r1, [r0, #MASK_IT_REG1]
+	strh	r1, [r0, #MASK_IT_REG2]
+
+@ now install our IRQ vector into the magic IRAM jump table slot
+
+	ldr	r0, =_INT_IRQ
+	mov	r1, #0x800000
+	str	r0, [r1, #0x14]
+
+@ we are done!
+	bx	lr
+
+/*
+ * Need to define an INT_Vectors_Loaded() function
+ * that returns 1.
+ */
+	.globl	INT_Vectors_Loaded
+INT_Vectors_Loaded:
+	mov	r0, #1
+	bx	lr
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nuc-fw/nucleus/demo/nucdemo.Makefile	Mon Nov 11 10:17:08 2013 +0000
@@ -0,0 +1,10 @@
+CC=	arm-elf-gcc
+CFLAGS=	-O2 -fno-builtin -mthumb-interwork -mthumb
+CPPFLAGS=-I../nucleus
+
+OBJS=	demo.o
+
+all:	${OBJS}
+
+clean:
+	rm -f *.[oa] *errs
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nuc-fw/nucleus/demo/sdc.c	Mon Nov 11 10:17:08 2013 +0000
@@ -0,0 +1,1033 @@
+/**************************************************************************
+*                                                                          
+*               Copyright Mentor Graphics Corporation 2002              
+*                         All Rights Reserved.                          
+*                                                                       
+* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS  
+* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS   
+* SUBJECT TO LICENSE TERMS.                                             
+*                                                                          
+***************************************************************************
+***************************************************************************
+*                                                                          
+* FILE NAME                               VERSION                          
+*                                                                          
+*  sdc.c                        Nucleus PLUS\ARM925\Code Composer 1.14.1 
+*                                                                          
+* DESCRIPTION                                                              
+*                                                                          
+*  This file contains the Serial Driver specific functions.                
+*                                                                          
+* DATA STRUCTURES                                                          
+*                                                                          
+*  SD_PORT *       :   An array of pointers to serial port structures.     
+*                                                                          
+* FUNCTIONS                                                                
+*                                                                          
+*  SDC_Init_Port                                                           
+*  SDC_Date_Ready                                                          
+*  SDC_Put_String                                                          
+*  SDC_LISR                                                                
+*  SDC_Get_Char                                                            
+*  SDC_Put_Char                                                            
+*  SDC_Set_Baud_Rate                                                       
+*                                                                          
+* DEPENDENCIES                                                             
+*                                                                          
+*  nucleus.h                                                               
+*  sd_defs.h                                                               
+*  sd_extr.h                                                               
+*   target.h                                                               
+* protocol.h                                                               
+*  externs.h                                                               
+*      ppp.h    
+*
+* HISTORY                                                               
+*                                                                       
+*         NAME            DATE                    REMARKS               
+*
+*      B. Ronquillo     08-28-2002           Released version 1.14.1    
+****************************************************************************/
+
+#include "nucleus.h"
+#include "sd_defs.h"
+#include "sd_extr.h"
+#include "calirq.h"
+
+#ifdef NU_ENABLE_PPP
+
+#include "net\target.h"
+#include "net\inc\externs.h"
+#include "net\inc\tcp_errs.h"
+#include "ppp\inc\ppp.h"
+
+#endif /* NU_ENABLE_PPP */
+
+extern NU_MEMORY_POOL   System_Memory;
+
+/* Define a small array to hold pointers to the two UART data
+   structures. This is used by the LISR to find the correct
+   data structure for the interrupt being handled. */
+SD_PORT         *SDC_Port_List[SD_MAX_UARTS];
+
+
+/* Define prototypes for functions local to this module. */
+
+    /**************** Begin Port Specific Section **************/
+#ifdef GRAFIX_MOUSE
+extern NU_HISR Mouse_HISR;
+#endif
+    /**************** End Port Specific Section **************/
+
+static  VOID    SDC_Set_Baud_Rate(UINT32, SD_PORT *);
+/***************************************************************************
+* FUNCTION
+*
+*    SDC_Init_Port
+*
+* DESCRIPTION
+*
+*    This function intializes the COM port that will be used for PPP
+*    communications.
+*
+*
+* INPUTS
+*
+*    SD_PORT *     :   device initialization structure.
+*
+* OUTPUTS
+*
+*    STATUS        :   Returns NU_SUCCESS if successful initialization,
+*                      else a negative value is returned.
+*
+****************************************************************************/
+STATUS  SDC_Init_Port(SD_PORT *uart)
+{
+STATUS      status = NU_SUCCESS;
+INT32       int_level,          /* old interrupt level */
+            tInt;
+UINT8       temp_byte;
+UINT32      temp_word, int_val;
+CHAR        sem_name[8];
+static INT  num_ports = 0;
+VOID        (*old_lisr)(INT);   /* old LISR */
+
+#ifdef GRAFIX_MOUSE
+    if ((uart->communication_mode == SERIAL_MODE) ||
+        (uart->communication_mode == SERIAL_MOUSE))
+#else
+    if (uart->communication_mode == SERIAL_MOUSE)
+    {
+        status = NU_INVALID_MOUSE_MODE;
+    }
+    else if (uart->communication_mode == SERIAL_MODE)
+#endif
+
+    {
+    
+        /* Check for max allowed UARTS. */
+        if (num_ports >= SD_MAX_UARTS)
+
+           /* We have already initialized the max allowed UARTS. */
+           status = NU_UART_LIST_FULL;
+    }
+    
+    if (status != NU_SUCCESS)
+        return (status);
+
+    /* Check the supplied parity */
+    else if ((uart->parity != SD_PARITY_NONE) &&
+             (uart->parity != SD_PARITY_EVEN) &&
+             (uart->parity != SD_PARITY_ODD))
+
+        /* The supplied parity is not valid */
+        status = NU_INVALID_PARITY;
+
+    /* Check the supplied number of data bits */
+    else if ((uart->data_bits != SD_DATA_BITS_7) &&
+             (uart->data_bits != SD_DATA_BITS_8))
+
+        /* The supplied data bits value is not valid */
+        status = NU_INVALID_DATA_BITS;
+
+    /* Check the supplied number of stop bits */
+    else if ((uart->stop_bits != SD_STOP_BITS_1) &&
+             (uart->stop_bits != SD_STOP_BITS_2))
+
+        /* The supplied stop bits value is not valid */
+        status = NU_INVALID_STOP_BITS;
+
+    /* Verify the baud rate is within acceptable range */
+    else if ((uart->baud_rate < 300) || (uart->baud_rate > 115200))
+
+        /* The baud rate is out of range */
+        status = NU_INVALID_BAUD;
+
+    /************** Begin Port Specific Section ****************/
+
+    /* Validate the com port. */
+    else if ((uart->com_port == SD_UART1) ||
+             (uart->com_port == SD_UART2))
+    {
+        /* Handle UARTA */
+        if (uart->com_port == SD_UART_MODEM)
+        {
+            /* Set the vector inside this structure */
+            uart->vector = IRQ_UART_MODEM;
+
+            /* Set the base address for this UART. */
+            uart->base_address = SD_UART_MODEM_BASE;
+        }
+        else    /* Otherwise handle UARTB. */
+        {
+            /* Set the vector inside this structure */
+            uart->vector = IRQ_UART_IRDA;
+            
+            /* Set the base address for this UART. */
+            uart->base_address = SD_UART_IRDA_BASE;
+        }
+    }
+    else
+
+    /************** End Port Specific Section **************/
+
+        /* Not a supported port. */
+        status = NU_INVALID_COM_PORT;
+
+#ifdef GRAFIX_MOUSE
+    if ((uart->communication_mode == SERIAL_MODE) ||
+        (uart->communication_mode == SERIAL_MOUSE))
+#else
+    if (uart->communication_mode == SERIAL_MODE)
+#endif
+
+    {
+        /* Make sure the port was valid and the LISR was
+           registered. Then create the semaphore used to make
+           the SD_Put_String service thread safe. */
+        if (status == NU_SUCCESS)
+        {
+            /* Allocate memory for the semaphore control block. */
+           status = NU_Allocate_Memory(&System_Memory,(VOID**) &uart->sd_semaphore,
+                        sizeof(NU_SEMAPHORE), NU_NO_SUSPEND);
+
+#if 0
+/* original code */
+            for(tInt=0; tInt < sizeof(NU_SEMAPHORE); tInt++)
+                       /* Fixed SPR 211.  Changed type from (UINT32) to (CHAR *) */
+                       SD_OUTBYTE((CHAR *) uart->sd_semaphore + tInt, 0x00);
+#else
+	    bzero(uart->sd_semaphore, sizeof(NU_SEMAPHORE));
+#endif
+
+            if (status == NU_SUCCESS)
+            {
+                /* Build the name. */
+                sem_name[0] = 's';
+                sem_name[1] = 'e';
+                sem_name[2] = 'r';
+                sem_name[3] = 'i';
+                sem_name[4] = 'a';
+                sem_name[5] = 'l';
+                sem_name[6] = '_';
+                sem_name[7] = (CHAR)(0x30 + num_ports);
+
+                status = NU_Create_Semaphore (uart->sd_semaphore, sem_name,
+                                              1, NU_FIFO);
+            }                                   
+        }
+
+        /* Make sure all the above was completed. Then store off this
+           UART stucture and initialize the chip. */
+        if (status == NU_SUCCESS)
+        {
+            SDC_Port_List[num_ports++] = uart;
+        }
+    }
+
+    if (status == NU_SUCCESS)
+    {
+        /* Allocate memory for the data buffers. PPP only requires a TX
+           buffer so the allocation will be a little different for PPP mode. */
+#ifdef GRAFIX_MOUSE
+        if ((uart->communication_mode == SERIAL_MODE) ||
+            (uart->communication_mode == SERIAL_MOUSE))
+#else
+        if (uart->communication_mode == SERIAL_MODE)
+#endif
+
+        {
+            status = NU_Allocate_Memory (&System_Memory,(VOID**) &uart->tx_buffer, 
+                         (2 * uart->sd_buffer_size), NU_NO_SUSPEND);
+
+            /* Set the RX buffer to just past the TX buffer. */
+            uart->rx_buffer = (CHAR *)(uart->tx_buffer + uart->sd_buffer_size);
+        }
+        else
+        {
+            status = NU_Allocate_Memory (&System_Memory,(VOID**) &uart->tx_buffer, 
+                         uart->sd_buffer_size, NU_NO_SUSPEND);
+        }
+
+        if (status == NU_SUCCESS)
+        {
+            /* Setup the RX SD buffer */
+            uart->rx_buffer_read = uart->rx_buffer_write = 0;
+ 
+            uart->rx_buffer_status = NU_BUFFER_EMPTY;
+
+            /* Setup the TX SD buffer */
+            uart->tx_buffer_read = uart->tx_buffer_write = 0;
+            uart->tx_buffer_status = NU_BUFFER_EMPTY;
+        }
+    }
+
+    if (status == NU_SUCCESS)
+    {
+        /* Disable interrupts */
+        int_level = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);
+
+        /* Initialize the UART */
+
+        /************** Begin Port Specific Section *************/
+
+        /* Configure the Mode Definition Register */
+        /* Set the serial port to UART mode */
+        SD_OUTBYTE(uart->base_address + MDR_OFFSET, MDR_UART_MODE);
+
+        /* Reset the TX/RX FIFOs */
+        SD_OUTBYTE(uart->base_address + FCR_OFFSET, FCR_FIFO_RESET);
+
+        /* Setup baud rate */
+        SDC_Set_Baud_Rate(uart->baud_rate, uart);
+
+        /* Set the modem control register. Set DTR, RTS to output to LOW,
+           and set INT output pin to normal operating mode */ 
+        SD_OUTBYTE (uart->base_address + MCR_OFFSET, (MCR_DTR_LOW | MCR_RTS_LOW)); 
+
+        /* Setup parity, data bits, and stop bits */
+        SD_OUTBYTE (uart->base_address + LCR_OFFSET,
+                          (LCR_NO_BREAK|uart->parity|uart->data_bits|uart->stop_bits ));
+
+        /* Setup Fifo trigger level and enable FIFO */
+        SD_OUTBYTE (uart->base_address + FCR_OFFSET, 0);
+
+        /* Register the interrupt handler for the UART receiver */
+        status = NU_Register_LISR(uart->vector, SDC_LISR, &old_lisr);
+
+        if (status == NU_SUCCESS)
+        {
+            /* Enable the RX interrupts */
+            SD_OUTBYTE (uart->base_address + IER_OFFSET, IER_RX_HOLDING_REG);
+
+            if(uart->com_port == SD_UART_MODEM)
+            {
+                /* Enable the UART interrupt globally */
+		INTH_REGS.ilr_irq[IRQ_UART_MODEM] = 0x7C;
+		INTH_REGS.mask_it_reg1 &= ~(1 << IRQ_UART_MODEM);
+            }
+            else  /* Handle UART B */
+            {    
+                /* Enable the UART interrupt globally */
+		INTH_REGS.ilr_irq[IRQ_UART_IRDA] = 0x7C;
+		INTH_REGS.mask_it_reg2 &= ~(1 << (IRQ_UART_IRDA - 16));
+            }
+
+        }
+
+        /************** End Port Specific Section *************/
+
+
+        /* Initialize the error counters. */
+        uart->parity_errors   =
+        uart->frame_errors    =
+        uart->overrun_errors  = 
+        uart->busy_errors     = 
+        uart->general_errors  = 0;
+
+        /* Restore interrupts to previous level */
+        NU_Local_Control_Interrupts(int_level);
+    }
+
+    return (status);
+}
+/***************************************************************************
+* FUNCTION
+*
+*    SDC_Put_Char
+*
+* DESCRIPTION
+*
+*    This writes a character out to the serial port.
+*
+* INPUTS
+*
+*    UINT8 :   Character to to be written to the serial port.
+*    SD_PORT *     :   Serial port to send the char to.
+*
+* OUTPUTS
+*
+*    none
+*
+****************************************************************************/
+VOID  SDC_Put_Char(UINT8 ch, SD_PORT *uart)
+{
+INT         int_level;          /* old interrupt level */
+UINT32  temp_long;
+
+#ifdef GRAFIX_MOUSE
+    if ((uart->communication_mode == SERIAL_MODE) ||
+        (uart->communication_mode == SERIAL_MOUSE))
+#else
+    if (uart->communication_mode == SERIAL_MODE)
+#endif
+
+    {
+        /* If the buffer is full wait for it to empty a little. */
+        while (uart->tx_buffer_status == NU_BUFFER_FULL);
+
+        /* Disable interrupts */
+        int_level = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);
+
+        /* Check the transmit buffer status. If it has data already
+           just add this byte to the buffer. */
+         if ( uart->tx_buffer_status != NU_BUFFER_EMPTY)
+        {
+            /* Add byte to buffer. */
+            uart->tx_buffer[uart->tx_buffer_write++] = ch;
+
+            /* Check for wrap of buffer. */
+            if(uart->tx_buffer_write == uart->sd_buffer_size)
+                uart->tx_buffer_write = 0;
+          
+            /* Check for full buffer. */
+            if (uart->tx_buffer_write == uart->tx_buffer_read) 
+                uart->tx_buffer_status = NU_BUFFER_FULL;
+
+            /* Restore interrupts to previous level */
+            NU_Local_Control_Interrupts(int_level);
+        }
+        else
+        {
+            /* Otherwise send the data. */
+
+            /* Restore interrupts to previous level */
+            NU_Local_Control_Interrupts(int_level);
+
+            /* Add byte to buffer. */
+            uart->tx_buffer[uart->tx_buffer_write++] = ch;
+
+            /* Check for wrap of buffer. */
+            if(uart->tx_buffer_write == uart->sd_buffer_size)
+                uart->tx_buffer_write = 0;
+             
+            /* Set status */
+            uart->tx_buffer_status = NU_BUFFER_DATA;
+
+            /**************** Begin Port Specific Section **************/
+
+            /* Wait until the transmitter buffer is empty */
+            while (!(SD_INBYTE (uart->base_address + LSR_OFFSET) & LSR_TX_HOLD_EMPTY));
+
+            /* Transmit the character */
+            SD_OUTBYTE (uart->base_address + THR_OFFSET, ch);
+
+            /* Enable the TX interrupts */
+            temp_long = SD_INBYTE (uart->base_address + IER_OFFSET);
+            temp_long |= IER_TX_HOLDING_REG;
+            SD_OUTBYTE (uart->base_address + IER_OFFSET, temp_long);               
+
+        }
+    
+    }  /* endif mode */
+    else 
+    {
+        /* Wait until the transmitter buffer is empty */
+        while (!(SD_INBYTE (uart->base_address + LSR_OFFSET) & LSR_TX_HOLD_EMPTY));
+
+        /* Transmit the character */
+          SD_OUTBYTE (uart->base_address + THR_OFFSET, ch);
+
+#ifndef PPP_POLLED_TX
+
+            /* Enable the TX interrupts */
+            temp_long = SD_INBYTE (uart->base_address + IER_OFFSET);
+            temp_long |= IER_TX_HOLDING_REG;
+            SD_OUTBYTE (uart->base_address + IER_OFFSET, temp_long);
+                 
+#endif /* PPP_POLLED_TX */
+
+
+    }
+
+        /***************** End Port Specific Section ***************/
+
+}
+
+/***************************************************************************
+* FUNCTION
+*
+*    SDC_LISR
+*
+* DESCRIPTION
+*
+*    This is the entry function for the receive ISR that services the UART
+*    in the ARM925.
+*
+* INPUTS
+*
+*    INT         :   Interrupt vector
+*
+* OUTPUTS
+*
+*    none
+*
+****************************************************************************/
+VOID  SDC_LISR(INT vector)
+{
+
+SD_PORT         *uart;
+CHAR            receive;
+UINT8           status;
+UINT8           int_status;
+UINT8           vector_found = NU_FALSE;
+UINT8           ier_val;
+
+
+#ifdef NU_ENABLE_PPP
+DV_DEVICE_ENTRY *device;
+#endif /* NU_ENABLE_PPP */
+
+    for(receive = 0 ; (SDC_Port_List[receive] != NU_NULL) &&
+        (receive < SD_MAX_UARTS) && !vector_found ; receive++)
+    {
+        /* See if we found one. Better have since we got an interrupt
+           from one. */
+        if (SDC_Port_List[receive] -> vector == vector)
+        {
+            /* Point our local structure to it. */
+            uart = SDC_Port_List[receive];
+            vector_found = NU_TRUE;
+        }
+    }
+
+#ifdef  NU_ENABLE_PPP
+
+    /* Find the device for this interrupt */
+    if ( (device = DEV_Get_Dev_For_Vector(vector)) != NU_NULL)
+    {
+        /* Get the address of the uart structure for this device. */ 
+        uart = &((PPP_LAYER *) device->ppp_layer)->uart;
+        vector_found = NU_TRUE;    
+    }
+
+#endif /* NU_ENABLE_PPP */
+    
+    if (vector_found == NU_TRUE)
+    {
+        /**************** Begin Port Specific Section **************/
+
+        /* Get the interrupt status register value */
+        int_status = SD_INBYTE(uart->base_address + IIR_OFFSET);
+
+        /* Loop until all interrupts are processed */
+        while (!(int_status & IIR_PENDING))
+        {
+            /* Check for a receive interrupt */
+            if (((int_status & IIR_RX_LINE_STAT) ==IIR_RX_LINE_STAT) ||
+                ((int_status & IIR_RX_RDY) ==IIR_RX_RDY) ||
+                ((int_status & IIR_RX_TIMEOUT) ==IIR_RX_TIMEOUT) )
+            {
+               /* Process every character in the receive FIFO */
+                status = SD_INBYTE(uart->base_address + LSR_OFFSET);
+
+                while (status & LSR_RX_DATA_READY)
+                {
+                    /* Get character from receive FIFO */
+                    receive = SD_INBYTE (uart->base_address + RHR_OFFSET);
+
+                    /* Check if receive character has errors */
+                    if (status & (LSR_FRAMING_ERROR | LSR_PARITY_ERROR))
+                    {
+                        /* Increment parity errors if necessary */
+                        uart->parity_errors += ((status & LSR_PARITY_ERROR) == LSR_PARITY_ERROR);
+
+                        /* Increment framing errors if necessary */
+                        uart->frame_errors += ((status & LSR_FRAMING_ERROR) == LSR_FRAMING_ERROR);
+                    }
+                    else    // no framing or parity errors
+                    {
+                        /* Increment overrun errors if necessary */
+                        uart->overrun_errors += ((status & LSR_RX_DATA_READY) == LSR_RX_DATA_READY);
+
+                        /* Switch based on UART mode */
+                        switch(uart->communication_mode)
+                        {
+                            case SERIAL_MODE: 
+
+                                if (uart->rx_buffer_status != NU_BUFFER_FULL)
+                                {
+                
+                                    /* Put the character into the buffer */
+                                    uart->rx_buffer[uart->rx_buffer_write++] = receive;
+
+                                    /* Check for wrap of buffer. */
+                                    if(uart->rx_buffer_write == uart->sd_buffer_size)
+                                        uart->rx_buffer_write = 0;
+                                    
+                                    /* Set status field based on latest character */
+                                    if (uart->rx_buffer_write == uart->rx_buffer_read)
+                                        uart->rx_buffer_status = NU_BUFFER_FULL;
+                                    else
+                                        uart->rx_buffer_status = NU_BUFFER_DATA;
+                                }
+                                else
+                                    uart->busy_errors++;
+
+                            break;
+                    
+#ifdef NU_ENABLE_PPP
+                            /* call PPP processing functions */
+
+                            case MDM_NETWORK_COMMUNICATION:
+                                /* Call this devices receive routine */
+                                device->dev_receive(device);
+                            break;
+
+                            case MDM_TERMINAL_COMMUNICATION:
+                            default:
+                                MDM_Receive(device);
+                            break;
+#endif /* NU_ENABLE_PPP */
+                        } 
+                    }
+
+                    /* Check the rx buffer status again... */
+                    status = SD_INBYTE(uart->base_address + LSR_OFFSET);
+
+                }
+
+            }   // if ((status & IIR_TYPE_MASK) == IIR_Rx_Rdy)
+
+
+            int_status = SD_INBYTE(uart->base_address + IER_OFFSET);
+
+            if (int_status & IER_TX_HOLDING_REG)
+            {
+               if (uart->communication_mode == SERIAL_MODE)
+                {    
+                    /* Bump the read pointer past the byte that was just
+                       transmitted. */
+                    ++(uart->tx_buffer_read);
+                
+                    /* Check for wrap of buffer. */
+                    if(uart->tx_buffer_read == uart->sd_buffer_size)
+                        uart->tx_buffer_read = 0;
+
+                    /* Update the status. */
+                    if (uart->tx_buffer_write == uart->tx_buffer_read)
+                    {
+                       uart->tx_buffer_status = NU_BUFFER_EMPTY;
+
+                        /* Since it is now empty disable the TX interrupt! */
+                        ier_val =  SD_INBYTE(uart->base_address + IER_OFFSET);
+                        ier_val &= ~IER_TX_HOLDING_REG;
+                        SD_OUTBYTE(uart->base_address + IER_OFFSET, ier_val);
+                    }
+                    else
+                    {
+
+                        /* Wait until the transmitter buffer is empty */
+                        while (!(SD_INBYTE (uart->base_address + LSR_OFFSET) & LSR_TX_HOLD_EMPTY));
+
+                        /* Send the next byte in the queue. */
+                        SD_OUTBYTE(uart->base_address + THR_OFFSET, uart->tx_buffer[uart->tx_buffer_read]);
+                        
+                        /* Update the status. */
+                        uart->tx_buffer_status = NU_BUFFER_DATA;
+                    }
+                }
+#ifdef NU_ENABLE_PPP
+               else
+                {
+#ifndef PPP_POLLED_TX
+                   /* Check for a transmit interrupt. */
+                   /* Is there another byte in the TX buffer to send? */
+                   if (uart->tx_buffer_read != uart->tx_buffer_write)
+                   {
+                        /* Wait until the transmitter buffer is empty */
+                        while (!(SD_INBYTE (uart->base_address + LSR_OFFSET) & LSR_TX_HOLD_EMPTY));
+
+                        /* Send the next byte in the queue. */
+                        SD_OUTBYTE (uart->base_address + THR_OFFSET, uart->tx_buffer[uart->tx_buffer_read++]); 
+                        
+                        /* Check for wrap of buffer. */
+                        uart->tx_buffer_read %= uart->sd_buffer_size;
+                   }
+                   else
+                   {
+                   
+                        /* Since it is now empty disable the TX interrupt! */
+                        ier_val =  SD_INBYTE (uart->base_address + IER_OFFSET);
+                        ier_val &= ~IER_TX_HOLDING_REG;
+                        SD_OUTBYTE (uart->base_address + IER_OFFSET, ier_val);
+
+                       /* Only activate the HISR if we are tranmitting
+                          network data. */
+                       if (uart->communication_mode == MDM_NETWORK_COMMUNICATION)
+                       {
+                            /* Add this device to the list of PPP devices that have finished
+                               sending a packet. */
+                            _ppp_tx_dev_ptr_queue [_ppp_tx_dev_ptr_queue_write++] = device;
+
+                            /* Activate the HISR that will take care of processing the
+                               next packet in queue, if one is ready. */
+                            NU_Activate_HISR (&PPP_TX_HISR);
+
+                            /* Check for wrap of ring buffer. */
+                
+                            _ppp_tx_dev_ptr_queue_write %= PPP_MAX_TX_QUEUE_PTRS;
+
+                       }
+                    }
+#endif /* PPP_POLLED_TX */
+                }
+#endif /* NU_ENABLE_PPP */
+            }
+
+            /* Get the interrupt status register value */
+            int_status = SD_INBYTE(uart->base_address + IIR_OFFSET);
+        }
+        
+        /**************** End Port Specific Section **************/
+    
+        /* No port is associated with the vector */
+    }
+    else 
+    {
+        ERC_System_Error(NU_UNHANDLED_INTERRUPT);
+    }   
+}
+
+/****************************************************************************
+* FUNCTION
+*
+*    SDC_Set_Baud_Rate
+*
+* DESCRIPTION
+*
+*    This function sets the UART buad rate.
+*
+* INPUTS
+*
+*    UINT32      :  The new baud rate.
+*    SD_PORT *     :  Serial port to set the baud rate.
+*
+* OUTPUTS
+*
+*    none
+*
+****************************************************************************/
+VOID  SDC_Set_Baud_Rate(UINT32 baud_rate, SD_PORT *uart)
+{
+    UNSIGNED    baud_div;
+    UINT32      temp_long;
+
+    /**************** Begin Port Specific Section **************/
+
+    /* Write to the divisor latch bit to enable the DLH and DLL registers */
+    temp_long = SD_INBYTE(uart->base_address + LCR_OFFSET);
+    SD_OUTBYTE (uart->base_address + LCR_OFFSET, LCR_DIV_EN);             
+
+    /* Set the baud rate */
+    baud_div = 115200 * 7 / uart->baud_rate;
+
+    /* Put LSB in DLL Reg */
+    SD_OUTBYTE (uart->base_address + DLL_OFFSET, baud_div);
+
+    /* Put MSB in DLH Reg */    
+    SD_OUTBYTE (uart->base_address + DLH_OFFSET, (baud_div >> 8));
+
+    /* Disable the Divisor Latch bit */
+    SD_OUTBYTE (uart->base_address + LCR_OFFSET, temp_long & ~LCR_DIV_EN);             
+   /**************** End Port Specific Section ****************/
+
+}
+/****************************************************************************
+* FUNCTION
+*
+*    SDC_Get_Char
+*
+* DESCRIPTION
+*
+*    This function reads the last received character from the UART.
+*
+* INPUTS
+*
+*    SD_PORT *      :   Serial port to get the char from.
+*
+* OUTPUTS
+*
+*    CHAR  :  Character read
+*
+****************************************************************************/
+CHAR  SDC_Get_Char(SD_PORT *uart)
+{
+    CHAR    ch = NU_NULL;
+
+#ifdef GRAFIX_MOUSE
+    if ((uart->communication_mode == SERIAL_MODE) ||
+        (uart->communication_mode == SERIAL_MOUSE))
+#else
+    if (uart->communication_mode == SERIAL_MODE)
+#endif
+
+    {
+        if ((uart->rx_buffer_status == NU_BUFFER_FULL) ||
+            (uart->rx_buffer_status == NU_BUFFER_DATA))
+        {
+            /* Store the character to be returned */
+            ch = uart->rx_buffer[uart->rx_buffer_read++]; 
+
+            /* If read pointer is at end, wrap it around */
+            if (uart->rx_buffer_read == uart->sd_buffer_size)
+                uart->rx_buffer_read = 0;
+
+            /* Set the status to reflect removal of the character */
+            if (uart->rx_buffer_write == uart->rx_buffer_read)
+                uart->rx_buffer_status = NU_BUFFER_EMPTY;
+            else
+                uart->rx_buffer_status = NU_BUFFER_DATA;
+        }
+
+        return (ch);
+    } /* endif mode */
+
+#ifdef NU_ENABLE_PPP
+    else if (uart->communication_mode == MDM_TERMINAL_COMMUNICATION || 
+             uart->communication_mode == MDM_NETWORK_COMMUNICATION)
+
+    /**************** Begin Port Specific Section **************/
+
+             return ((UINT8)SD_INBYTE (uart->base_address + RHR_OFFSET));
+
+    /**************** End Port Specific Section ****************/
+
+#endif /* NU_ENABLE_PPP */
+
+    /* Execution should never reach this point, this return was added
+       in response to the 'implicit return' compiler warning */
+
+    return (ch);
+}
+
+/****************************************************************************
+* FUNCTION
+*
+*    SDC_Carrier
+*
+* DESCRIPTION
+*
+*    This function checks for a carrier.
+*
+* INPUTS
+*
+*    none
+*
+* OUTPUTS
+*
+*    STATUS    :  The status of the detection.
+*
+****************************************************************************/
+STATUS SDC_Carrier(SD_PORT *uart)
+{
+    return (NU_TRUE);
+}
+
+/****************************************************************************
+ Note: All functions below this point are generic and should not require
+       any changes to support other UARTS.
+ ****************************************************************************/
+
+/****************************************************************************
+* FUNCTION
+*
+*    SDC_Put_String
+*
+* DESCRIPTION
+*
+*    This writes a null-terminated string out to the serial port.
+*
+* INPUTS
+*
+*    CHAR *        :   String to be written to the serial port.
+*    SD_PORT *     :   Serial port to send the string to.
+*
+* OUTPUTS
+*
+*    none
+*
+****************************************************************************/
+VOID SDC_Put_String(CHAR *str, SD_PORT *uart)
+{
+
+   /* Grab the semaphore so that strings between threads
+       do not get mixed. */
+    if (NU_Obtain_Semaphore(uart->sd_semaphore, NU_SUSPEND) == NU_SUCCESS)
+    {
+
+        /* Send out the string. */
+        for (; *str != 0; str++)
+            SDC_Put_Char(*str, uart);
+
+        /* Allow other threads to use this service. */
+        NU_Release_Semaphore (uart->sd_semaphore);
+    }
+
+}
+
+
+/****************************************************************************
+* FUNCTION
+*
+*    SDC_Data_Ready
+*
+* DESCRIPTION
+*
+*    This function checks to see if there are any characters in the
+*    receive buffer.  A status value is returned indicating whether
+*    characters are present in the receive buffer.
+*
+* INPUTS
+*
+*    SD_PORT *      :   Serial port to check for data.
+*
+* OUTPUTS
+*
+*    STATUS                                The status indicates the
+*                                          presence of characters.
+*
+****************************************************************************/
+STATUS SDC_Data_Ready(SD_PORT *port)
+{
+    /* Check the status. */
+    if((port->rx_buffer_status == NU_BUFFER_FULL) ||
+       (port->rx_buffer_status == NU_BUFFER_DATA))
+
+        return (NU_TRUE);
+
+    else
+
+        return (NU_FALSE);
+}
+
+/****************************************************************************
+* FUNCTION
+*
+*    SDC_Change_Communication_Mode
+*
+* DESCRIPTION
+*
+*    This function switches the serial port between terminal mode and
+*    network mode.  The mode affects how incoming characters are directed.
+*
+* INPUTS
+*
+*    INT      :  The mode of operation desired.
+*
+* OUTPUTS
+*
+*    none
+*
+****************************************************************************/
+VOID SDC_Change_Communication_Mode(INT mode, SD_PORT *uart)
+{
+    uart->communication_mode = mode;
+
+} /* SDC_Change_Communication_Mode */
+
+/****************************************************************************
+* FUNCTION
+*
+*    SDC_Reset
+*
+* DESCRIPTION
+*
+*    This function intializes the data variables associated with a UART
+*
+* INPUTS
+*
+*    SD_PORT      * :   Serial port to reset
+*
+* OUTPUTS
+*
+*    STATUS      :   Returns URT_SUCCESS if successful initialization,
+*                    else a negative value is returned.
+*
+****************************************************************************/
+VOID SDC_Reset (SD_PORT *uart)
+{
+    /* Ini the error counters */
+    uart->frame_errors   = 0;
+    uart->overrun_errors = 0;
+    uart->parity_errors  = 0;
+    uart->busy_errors    = 0;
+    uart->general_errors = 0;
+}
+
+/***************************************************************************
+* FUNCTION
+*
+*    URT_Init_Port
+*
+* DESCRIPTION
+*
+*    This function intializes the data variables associated with a UART
+*
+* INPUTS
+*
+*    SD_PORT      * :   Serial port to reset
+*
+* OUTPUTS
+*
+*    STATUS      :   Returns URT_SUCCESS if successful initialization,
+*                    else a negative value is returned.
+*
+****************************************************************************/
+#ifdef NU_ENABLE_PPP
+STATUS  URT_Init_Port(DV_DEVICE_ENTRY *device)
+{
+    SD_PORT   *uart;
+    STATUS    ret_status;
+
+    /* Get a pointer to the UART layer of this device. */
+    uart = &((PPP_LAYER *) device->ppp_layer)->uart;
+
+    /* Init the serial port, copy init parameters from the device 
+       structure. */
+    uart->com_port              = device->dev_com_port;
+    uart->baud_rate             = device->dev_baud_rate;
+    uart->data_bits             = device->dev_data_bits;
+    uart->stop_bits             = device->dev_stop_bits;
+    uart->parity                = device->dev_parity;
+    uart->data_mode             = device->dev_data_mode;
+    uart->vector                = device->dev_vect;
+    uart->driver_options        = device->dev_driver_options;
+    uart->communication_mode    = MDM_TERMINAL_COMMUNICATION;
+    uart->sd_buffer_size        = (2 * (PPP_MTU + PPP_FCS_SIZE + 
+                                    PPP_MAX_PROTOCOL_SIZE + PPP_MAX_ADDR_CONTROL_SIZE));
+
+    /* Init the port */
+    ret_status = NU_SD_Init_Port (uart);
+
+    if (ret_status == NU_SUCCESS)
+    {
+        /* Copy the vector back into the device entry just in case
+           the UART driver changed it. */
+        device->dev_vect = uart->vector;
+    }
+
+    return (ret_status);
+
+}
+#endif /* NU_ENABLE_PPP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nuc-fw/nucleus/demo/tmcal.c	Mon Nov 11 10:17:08 2013 +0000
@@ -0,0 +1,23 @@
+/*
+ * FreeNucleus port by Spacefalcon the Outlaw
+ *
+ * This module implements the INT_Timer_Initialize() function
+ * for the proof-of-concept Calypso port.
+ *
+ * TIMER2 configuration is based on that used by OsmocomBB.
+ */
+
+#include "calirq.h"
+#include "caltimer.h"
+
+void
+INT_Timer_Initialize()
+{
+	/* program the timer */
+	TIMER2_REGS.cntl = CNTL_CLOCK_ENABLE;
+	TIMER2_REGS.load = 4062;
+	TIMER2_REGS.cntl = CNTL_CLOCK_ENABLE | CNTL_AUTO_RELOAD | CNTL_START;
+	/* now let it interrupt */
+	INTH_REGS.ilr_irq[IRQ_TIMER2] = 0x7E;
+	INTH_REGS.mask_it_reg1 &= ~(1 << IRQ_TIMER2);
+}
--- a/nuc-fw/nucleus/irqshell.S	Mon Nov 11 09:56:23 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,584 +0,0 @@
-/*
- * FreeNucleus Calypso port by Michael Spacefalcon
- *
- * This assembly module contains IRQ handler shell
- * and some closely related support functions.
- *
- * The approach to IRQ handling implemented in the present version
- * is exactly the same as was found in XVilka's original nucleus_plus.tar.gz
- * code targeting OMAP1510.  I personally consider it very dumb and
- * suboptimal, but the present version is merely a proof of concept -
- * changing as little as possible from our starting point will (hopefully)
- * make it easier to get this code to compile, link and maybe even run.
- */
-
-#include "asm_defs.h"
-#include "calirq.h"
-
-	.code 32
-
-/*
- **********************************
- * GLOBAL VARIABLE DECLARATIONS   *
- **********************************
- */
-
-	.data
-
-@ Define vector table used by INT_IRQ to branch to necessary ISR
-
-	.globl	INT_IRQ_Vectors
-INT_IRQ_Vectors:
-    .word     INT_Interrupt_Shell             @ Vector 0
-    .word     INT_Interrupt_Shell             @ Vector 1
-    .word     INT_Timer_Interrupt             @ Vector 2 - TIMER2
-    .word     INT_Interrupt_Shell             @ Vector 3
-    .word     INT_Interrupt_Shell             @ Vector 4
-    .word     INT_Interrupt_Shell             @ Vector 5
-    .word     INT_Interrupt_Shell             @ Vector 6
-    .word     INT_Interrupt_Shell             @ Vector 7
-    .word     INT_Interrupt_Shell             @ Vector 8
-    .word     INT_Interrupt_Shell             @ Vector 9
-    .word     INT_Interrupt_Shell             @ Vector 10
-    .word     INT_Interrupt_Shell             @ Vector 11
-    .word     INT_Interrupt_Shell             @ Vector 12
-    .word     INT_Interrupt_Shell             @ Vector 13
-    .word     INT_Interrupt_Shell             @ Vector 14
-    .word     INT_Interrupt_Shell             @ Vector 15
-    .word     INT_Interrupt_Shell             @ Vector 16
-    .word     INT_Interrupt_Shell             @ Vector 17
-    .word     INT_Interrupt_Shell             @ Vector 18
-    .word     INT_Interrupt_Shell             @ Vector 19
-    .word     INT_Interrupt_Shell             @ Vector 20
-
-@ Define the order in which the interrupts will be executed by software(INT_IRQ)
-@ Level 1 Interrupt Handler
-	.globl	INT_IRQ_Priority
-INT_IRQ_Priority:
-	.word	0
-	.word	1
-	.word	2
-	.word	3
-	.word	4
-	.word	5
-	.word	6
-	.word	7
-	.word	8
-	.word	9
-	.word	10
-	.word	11
-	.word	12
-	.word	13
-	.word	14
-	.word	15
-	.word	16
-	.word	17
-	.word	18
-	.word	19
-	.word	20
-INT_Priority_End:
-
-	.text
-
-/*
- ************************************************************************
- *                                                                       
- * FUNCTION                                                              
- *                                                                       
- *      INT_Setup_Vector                                                 
- *                                                                       
- * DESCRIPTION                                                           
- *                                                                       
- *      This function sets up the specified vector with the new vector   
- *      value.  The previous vector value is returned to the caller.     
- *                                                                       
- *                                                                       
- *      Major Revision:                                                  
- *                                                                       
- *          M. Kyle Craig, Accelerated Technology, Inc.                  
- *                                                                       
- *                                                                       
- *                                                                       
- * CALLED BY                                                             
- *                                                                       
- *      Application                                                      
- *      TCC_Register_LISR                   Register LISR for vector     
- *                                                                       
- * CALLS                                                                 
- *                                                                       
- *      None                                                             
- *                                                                       
- * INPUTS                                                                
- *                                                                       
- *      vector                              Vector number to setup       
- *      new                                 Pointer to new assembly      
- *                                            language ISR               
- *                                                                       
- * OUTPUTS                                                               
- *                                                                       
- *      old vector contents                                              
- *                                                                       
- * HISTORY                                                               
- *                                                                       
- *         NAME            DATE                    REMARKS               
- *                                                                       
- *      W. Lamie        08-27-1994      Created initial version 1.0      
- *      D. Lamie        08-27-1994      Verified version 1.0             
- *                                                                       
- ************************************************************************
- */
-
-@VOID  *INT_Setup_Vector(INT vector, VOID *new)
-@{
-
-	.globl  INT_Setup_Vector
-INT_Setup_Vector:
-
-@VOID    *old_vector;                        /* Old interrupt vector      */
-@VOID   **vector_table;                      /* Pointer to vector table   */
-
-@ Calculate the starting address of the actual vector table.
-@    vector_table =  (VOID **) 0;
-
-@ Pickup the old interrupt vector.
-@    old_vector =  vector_table[vector];
-@    
-@ Setup the new interrupt vector.
-@    vector_table[vector] =  new;
-@    
-@ Return the old interrupt vector.
-@    return(old_vector);
-
-
-        LDR     r2, =INT_IRQ_Vectors        @ Load the vector table address
-        MOV     r0, r0, LSL #2              @ Multiply vector by 4 to get offset into table
-        LDR     r3, [r2,r0]                 @ Load the old pointer
-        STR     r1, [r2,r0]                 @ Store the new pointer into the vector table
-
-        MOV     r0, r3                      @ Put the old pointer into the return register
-
-        BX      lr                          @ Return to caller
-
-@}
-
-/*
- ************************************************************************
- *                                                                       
- * FUNCTION                                                              
- *                                                                       
- *      INT_Retrieve_Shell                                               
- *                                                                       
- * DESCRIPTION                                                           
- *                                                                       
- *      This function retrieves the pointer to the shell interrupt       
- *      service routine.  The shell interrupt service routine calls      
- *      the LISR dispatch routine.                                       
- *                                                                       
- *                                                                       
- *      Major Revision:                                                  
- *                                                                       
- *          M. Kyle Craig, Accelerated Technology, Inc.                  
- *                                                                       
- *                                                                       
- *                                                                       
- * CALLED BY                                                             
- *                                                                       
- *      TCC_Register_LISR                   Register LISR for vector     
- *                                                                       
- * CALLS                                                                 
- *                                                                       
- *      None                                                             
- *                                                                       
- * INPUTS                                                                
- *                                                                       
- *      vector                              Vector number to setup       
- *                                                                       
- * OUTPUTS                                                               
- *                                                                       
- *      shell pointer                                                    
- *                                                                       
- * HISTORY                                                               
- *                                                                       
- *         NAME            DATE                    REMARKS               
- *                                                                       
- *      W. Lamie        08-27-1994      Created initial version 1.0      
- *      D. Lamie        08-27-1994      Verified version 1.0             
- *                                                                       
- ************************************************************************
- */
-
-@VOID  *INT_Retrieve_Shell(INT vector)
-@{
-
-	.globl  INT_Retrieve_Shell
-INT_Retrieve_Shell:
-
-    @ Return the LISR Shell interrupt routine.
-    @ return(INT_Vectors[vector]);
-
-        LDR     r1, =INT_IRQ_Vectors        @ Load the vector table address
-        MOV     r0, r0, LSL #2              @ Multiply vector by 4 to get offset into table
-        LDR     r0, [r1,r0]                 @ Load interrupt handler pointer into return register
-                           
-        BX      lr                          @ Return to caller
-
-     
-@}
-
-/*
- ************************************************************************
- *
- * FUNCTION
- *
- *      _INT_IRQ
- *
- * DESCRIPTION
- *
- *      This routine is the board-specific section for
- *      level 1 interrupt handling
- *
- * CALLED BY                                                             
- *                                                                       
- *      None                                                             
- *                                                                       
- * CALLS                                                                 
- *                                                                       
- *      TMT_Timer_Interrupt                                              
- *                                                                       
- * INPUTS                                                                
- *                                                                       
- *      None                                                             
- *                                                                       
- *                                                                       
- * OUTPUTS                                                               
- *                                                                       
- *      None                                                             
- *                                                                       
- * HISTORY                                                               
- *                                                                       
- *         NAME            DATE                    REMARKS               
- *                                                                       
- *      B. Ronquillo      05-10-00        Created initial version 1.0      
- *                                                                       
- ************************************************************************
- */
-
-	.globl  _INT_IRQ
-_INT_IRQ:
-
-    STMDB   sp!,{r0-r4}                     @ Save r0-r4 on temporary IRQ stack
-    SUB     lr,lr,#4                        @ Adjust IRQ return address
-
-/*
- ********************************
- * Begin Hardware Specific Code *
- ********************************
- */
-
-    LDR     r3, =INTH_BASE_ADDR             @ load Interrupt Control Base
-    @ Get enable register value
-    @ original instr was: LDR     r4, [r3,#INT_CNTRL_MIR]
-    @ but on the Calypso we have to read two 16-bit regs
-    ldrh    r0, [r3, #MASK_IT_REG1]
-    ldrh    r1, [r3, #MASK_IT_REG2]
-    @ now combine them into a 32-bit word in r4 for the old code to work as-is
-    orr     r4, r0, r1, lsl #16
-
-/*
- ******************************
- * End Hardware Specific Code *  
- ******************************
- */
-
-    STMDB   sp!,{r4}                        @ Put the enable register value on the IRQ stack
-    MVN     r4,#0                           @ Start with 0xFFFFFFFF to allow nesting of interrupts
-
-/*
- ********************************
- * Begin Hardware Specific Code *
- ********************************
- */
-
-    @ Read Pending reg
-    @ original instr was: LDR     r2, [r3,#INT_CNTRL_ITR]
-    @ do the same trick as we did for the mask regs
-    ldrh    r0, [r3, #IT_REG1]
-    ldrh    r1, [r3, #IT_REG2]
-    orr     r2, r0, r1, lsl #16
-
-/*
- ******************************
- * End Hardware Specific Code *
- ******************************
- */
-
-    LDR     r3, =INT_IRQ_Priority           @ Get the Priority table address
-
-IRQ_VECTOR_LOOP:
-    LDR     r0, [r3,#0]                     @ Load first vector to be checked from priority table
-    MOV     r1, #1                          @ Build mask
-    MOV     r1, r1, LSL r0                  @ Use vector number to set mask to correct bit position
-    TST     r1, r2                          @ Test if pending bit is set
-    BNE     IRQ_VECTOR_FOUND                @ If bit is set, branch to found section...
-
-    BIC     r4,r4,r1                        @ Clear mask bit to keep higher priority ints active
-    ADD     r3, r3, #4                      @ Move to next word in the priority table
-    LDR     r0, =INT_Priority_End           @ Load the end address for the priority table
-    CMP     r0, r3                          @ Make sure not at the end of the table (shouldn't happen!)
-    BNE     IRQ_VECTOR_LOOP                 @ Continue to loop if not at the end of the table
-
-    @ No bits in pending register set, restore registers and exit interrupt servicing
-    ADD     sp,sp,#4                        @ Adjust sp above IRQ enable value
-    LDMIA   sp!,{r0-r4}                     @ Restore r0-r4
-    STMDB   sp!,{lr}                        @ Put return address for IRQ on stack
-    LDMIA   sp!,{pc}^                       @ return to the point of the exception and restore SPSR
- 
-IRQ_VECTOR_FOUND:
-
-/*
- ********************************
- * Begin Hardware Specific Code *
- ********************************
- */
-
-    LDR     r3, =INTH_BASE_ADDR             @ load Interrupt Control Base
-
-    MVN     r2, r1                          @ Get the inverse of the interrupt vector
-    @ Write a zero to the interrupt being handled (IT_REGn)
-    cmp     r0, #16
-    strloh  r2, [r3, #IT_REG1]
-    mov     r2, r2, lsr #16
-    strhsh  r2, [r3, #IT_REG2]
-
-    @ Read the Mask reg - just like we did before
-    ldrh    r1, [r3, #MASK_IT_REG1]
-    ldrh    r2, [r3, #MASK_IT_REG2]
-    orr     r2, r1, r2, lsl #16
-    @ was LDR     r2, [r3,#INT_CNTRL_MIR]
-
-    ORR     r4, r2, r4                      @ Turn off lower priority pending bits and currently masked bits
-
-    @ write both mask registers
-    @ was STR     r4, [r3,#INT_CNTRL_MIR]
-    strh    r4, [r3, #MASK_IT_REG1]
-    mov     r1, r4, lsr #16
-    strh    r1, [r3, #MASK_IT_REG2]
-
-    MOV     r1, #1                          @ Clear the pending interrupt 
-    STRH    r1, [r3,#IRQ_CTRL]              @ by writing a 1 to the Control Reg
-
-/*
- ******************************
- * End Hardware Specific Code *
- ******************************
- */
-
-    LDR     r3, =INT_IRQ_Vectors            @ Get IRQ vector table address
-    MOV     r2, r0, LSL #2                  @ Multiply vector by 4 to get offset into table
-    ADD     r3, r3, r2                      @ Adjust vector table address to correct offset
-    LDR     r2, [r3,#0]                     @ Load branch address from vector table
-
-    MOV     PC, r2                          @ Jump to correct branch location based on vector table
-
-@ END: INT_IRQ
-
-/*
- ************************************************************************
- *                                                                       
- * FUNCTION                                                              
- *                                                                         
- *     INT_Interrupt_Shell                                               
- *                                                                         
- * DESCRIPTION                                                           
- *                                                                         
- *     Handles all interrupts which use NU_Register_LISR.                
- *                                                                         
- *                                                                       
- * CALLED BY                                                             
- *                                                                       
- *      INT_IRQ                                                          
- *                                                                       
- * CALLS                                                                 
- *                                                                       
- *      TCT_Dispatch_LISR                                                
- *      TCT_Interrupt_Context_Restore                                    
- *                                                                       
- * INPUTS                                                                
- *                                                                       
- *      vector (register r0)                                             
- *                                                                       
- * OUTPUTS                                                               
- *                                                                       
- *      None                                  
- ************************************************************************
- */
-
-    .globl INT_Interrupt_Shell
-INT_Interrupt_Shell:
-
-    MOV     r4,lr                           @ Put IRQ return address into r4
-
-    BL      TCT_Interrupt_Context_Save
-
-    BL      TCC_Dispatch_LISR
-
-    MRS     r1,CPSR                         @ Pickup current CPSR
-    BIC     r1,r1,#MODE_MASK                @ Clear the mode bits
-    ORR     r1,r1,#(IRQ_MODE_OR_LOCKOUT)    @ Set the IRQ mode bits and Lockout interrupts
-    MSR     CPSR,r1                         @ Lockout interrupts/change to IRQ mode
-
-/*
- ********************************
- * Begin Hardware Specific Code *
- ********************************
- */
-    LDMIA   sp!,{r1}                        @ Get IRQ enable value off IRQ stack
-
-    LDR     r2, =INTH_BASE_ADDR             @ Get IRQ0 base register address
-    @ write it into both mask regs
-    @was STR     r1,[r2,#INT_CNTRL_MIR]
-    strh    r1, [r2, #MASK_IT_REG1]
-    mov     r1, r1, lsr #16
-    strh    r1, [r2, #MASK_IT_REG2]
-/*
- ******************************
- * End Hardware Specific Code *                                         
- ******************************
- */
-    
-    MRS     r1,CPSR                         @ Pickup current CPSR
-    BIC     r1,r1,#MODE_MASK                @ Clear the mode bits
-    ORR     r1,r1,#SUP_MODE                 @ Set the SVC mode bits
-    MSR     CPSR,r1                         @ Change to SVC mode
-
-    B       TCT_Interrupt_Context_Restore
-
-/*
- ************************************************************************
- *                                                                       
- * FUNCTION                                                              
- *                                                                       
- *      INT_Timer_Interrupt                                              
- *                                                                       
- * DESCRIPTION                                                           
- *                                                                       
- *      This routine is the board-specific section of the timer          
- *      interrupt handling                                               
- *                                                                       
- * CALLED BY                                                             
- *                                                                       
- *      None                                                             
- *                                                                       
- * CALLS                                                                 
- *                                                                       
- *      TMT_Timer_Interrupt                                              
- *                                                                       
- * INPUTS                                                                
- *                                                                       
- *      None                                                             
- *                                                                       
- *                                                                       
- * OUTPUTS                                                               
- *                                                                       
- *      None                                                             
- *                                                                       
- * HISTORY                                                               
- *                                                                       
- *         NAME            DATE                    REMARKS               
- *                                                                       
- *      B.Ronquillo        05-10-00          Created initial version 1.0   
- *                                                                       
- ************************************************************************
- */
-
-	.globl  INT_Timer_Interrupt
-INT_Timer_Interrupt:
-
-/*
- ********************************
- * Begin Hardware Specific Code *
- ********************************
- * Clear the pending timer interrupt
- *
- * This is done in the INT_IRQ function by writing a zero to the   
- * timer bit.
- *
- ******************************
- * End Hardware Specific Code *
- ******************************
- */
-
-    MOV     r4,lr                           @ Put IRQ return address into r4
-
-    BL      TCT_Interrupt_Context_Save
-
-    BL      TMT_Timer_Interrupt             @ Call the timer interrupt
-                                            @ processing.
-
-    MRS     r1,CPSR                         @ Pickup current CPSR
-    BIC     r1,r1,#MODE_MASK                @ Clear the mode bits
-    ORR     r1,r1,#IRQ_MODE                 @ Set the IRQ mode bits
-    MSR     CPSR,r1                         @ Change to IRQ mode
-
-/*
- ********************************
- * Begin Hardware Specific Code *
- ********************************
- */
-    LDMIA   sp!,{r1}                        @ Get IRQ enable value off IRQ stack
-
-    LDR     r2, =INTH_BASE_ADDR             @ Get IRQ0 base register address
-    @ write it into both mask regs
-    @was STR     r1,[r2,#INT_CNTRL_MIR]
-    strh    r1, [r2, #MASK_IT_REG1]
-    mov     r1, r1, lsr #16
-    strh    r1, [r2, #MASK_IT_REG2]
-/*
- ******************************
- * End Hardware Specific Code *                                         
- ******************************
- */
-
-    MRS     r1,CPSR                         @ Pickup current CPSR
-    BIC     r1,r1,#MODE_MASK                @ Clear the mode bits
-    ORR     r1,r1,#SUP_MODE                 @ Set the SVC mode bits
-    MSR     CPSR,r1                         @ Change to SVC mode
-
-    B       TCT_Interrupt_Context_Restore
-
-@}
-@ End of INT_Timer_Interrupt
-
-/*
- * INT_Interrupt_Init function written by Michael Spacefalcon
- * for the FreeNucleus Calypso port - takes the place of
- * INT_Install_Vector_Table, called from INT_Initialize.
- */
-
-	.globl	INT_Interrupt_Init
-INT_Interrupt_Init:
-
-@ first mask all interrupts in the INTH
-
-	ldr	r0, =INTH_BASE_ADDR
-	mvn	r1, #0
-	strh	r1, [r0, #MASK_IT_REG1]
-	strh	r1, [r0, #MASK_IT_REG2]
-
-@ now install our IRQ vector into the magic IRAM jump table slot
-
-	ldr	r0, =_INT_IRQ
-	mov	r1, #0x800000
-	str	r0, [r1, #0x14]
-
-@ we are done!
-	bx	lr
-
-/*
- * Need to define an INT_Vectors_Loaded() function
- * that returns 1.
- */
-	.globl	INT_Vectors_Loaded
-INT_Vectors_Loaded:
-	mov	r0, #1
-	bx	lr
--- a/nuc-fw/nucleus/sdc.c	Mon Nov 11 09:56:23 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1033 +0,0 @@
-/**************************************************************************
-*                                                                          
-*               Copyright Mentor Graphics Corporation 2002              
-*                         All Rights Reserved.                          
-*                                                                       
-* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS  
-* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS   
-* SUBJECT TO LICENSE TERMS.                                             
-*                                                                          
-***************************************************************************
-***************************************************************************
-*                                                                          
-* FILE NAME                               VERSION                          
-*                                                                          
-*  sdc.c                        Nucleus PLUS\ARM925\Code Composer 1.14.1 
-*                                                                          
-* DESCRIPTION                                                              
-*                                                                          
-*  This file contains the Serial Driver specific functions.                
-*                                                                          
-* DATA STRUCTURES                                                          
-*                                                                          
-*  SD_PORT *       :   An array of pointers to serial port structures.     
-*                                                                          
-* FUNCTIONS                                                                
-*                                                                          
-*  SDC_Init_Port                                                           
-*  SDC_Date_Ready                                                          
-*  SDC_Put_String                                                          
-*  SDC_LISR                                                                
-*  SDC_Get_Char                                                            
-*  SDC_Put_Char                                                            
-*  SDC_Set_Baud_Rate                                                       
-*                                                                          
-* DEPENDENCIES                                                             
-*                                                                          
-*  nucleus.h                                                               
-*  sd_defs.h                                                               
-*  sd_extr.h                                                               
-*   target.h                                                               
-* protocol.h                                                               
-*  externs.h                                                               
-*      ppp.h    
-*
-* HISTORY                                                               
-*                                                                       
-*         NAME            DATE                    REMARKS               
-*
-*      B. Ronquillo     08-28-2002           Released version 1.14.1    
-****************************************************************************/
-
-#include "nucleus.h"
-#include "sd_defs.h"
-#include "sd_extr.h"
-#include "calirq.h"
-
-#ifdef NU_ENABLE_PPP
-
-#include "net\target.h"
-#include "net\inc\externs.h"
-#include "net\inc\tcp_errs.h"
-#include "ppp\inc\ppp.h"
-
-#endif /* NU_ENABLE_PPP */
-
-extern NU_MEMORY_POOL   System_Memory;
-
-/* Define a small array to hold pointers to the two UART data
-   structures. This is used by the LISR to find the correct
-   data structure for the interrupt being handled. */
-SD_PORT         *SDC_Port_List[SD_MAX_UARTS];
-
-
-/* Define prototypes for functions local to this module. */
-
-    /**************** Begin Port Specific Section **************/
-#ifdef GRAFIX_MOUSE
-extern NU_HISR Mouse_HISR;
-#endif
-    /**************** End Port Specific Section **************/
-
-static  VOID    SDC_Set_Baud_Rate(UINT32, SD_PORT *);
-/***************************************************************************
-* FUNCTION
-*
-*    SDC_Init_Port
-*
-* DESCRIPTION
-*
-*    This function intializes the COM port that will be used for PPP
-*    communications.
-*
-*
-* INPUTS
-*
-*    SD_PORT *     :   device initialization structure.
-*
-* OUTPUTS
-*
-*    STATUS        :   Returns NU_SUCCESS if successful initialization,
-*                      else a negative value is returned.
-*
-****************************************************************************/
-STATUS  SDC_Init_Port(SD_PORT *uart)
-{
-STATUS      status = NU_SUCCESS;
-INT32       int_level,          /* old interrupt level */
-            tInt;
-UINT8       temp_byte;
-UINT32      temp_word, int_val;
-CHAR        sem_name[8];
-static INT  num_ports = 0;
-VOID        (*old_lisr)(INT);   /* old LISR */
-
-#ifdef GRAFIX_MOUSE
-    if ((uart->communication_mode == SERIAL_MODE) ||
-        (uart->communication_mode == SERIAL_MOUSE))
-#else
-    if (uart->communication_mode == SERIAL_MOUSE)
-    {
-        status = NU_INVALID_MOUSE_MODE;
-    }
-    else if (uart->communication_mode == SERIAL_MODE)
-#endif
-
-    {
-    
-        /* Check for max allowed UARTS. */
-        if (num_ports >= SD_MAX_UARTS)
-
-           /* We have already initialized the max allowed UARTS. */
-           status = NU_UART_LIST_FULL;
-    }
-    
-    if (status != NU_SUCCESS)
-        return (status);
-
-    /* Check the supplied parity */
-    else if ((uart->parity != SD_PARITY_NONE) &&
-             (uart->parity != SD_PARITY_EVEN) &&
-             (uart->parity != SD_PARITY_ODD))
-
-        /* The supplied parity is not valid */
-        status = NU_INVALID_PARITY;
-
-    /* Check the supplied number of data bits */
-    else if ((uart->data_bits != SD_DATA_BITS_7) &&
-             (uart->data_bits != SD_DATA_BITS_8))
-
-        /* The supplied data bits value is not valid */
-        status = NU_INVALID_DATA_BITS;
-
-    /* Check the supplied number of stop bits */
-    else if ((uart->stop_bits != SD_STOP_BITS_1) &&
-             (uart->stop_bits != SD_STOP_BITS_2))
-
-        /* The supplied stop bits value is not valid */
-        status = NU_INVALID_STOP_BITS;
-
-    /* Verify the baud rate is within acceptable range */
-    else if ((uart->baud_rate < 300) || (uart->baud_rate > 115200))
-
-        /* The baud rate is out of range */
-        status = NU_INVALID_BAUD;
-
-    /************** Begin Port Specific Section ****************/
-
-    /* Validate the com port. */
-    else if ((uart->com_port == SD_UART1) ||
-             (uart->com_port == SD_UART2))
-    {
-        /* Handle UARTA */
-        if (uart->com_port == SD_UART_MODEM)
-        {
-            /* Set the vector inside this structure */
-            uart->vector = IRQ_UART_MODEM;
-
-            /* Set the base address for this UART. */
-            uart->base_address = SD_UART_MODEM_BASE;
-        }
-        else    /* Otherwise handle UARTB. */
-        {
-            /* Set the vector inside this structure */
-            uart->vector = IRQ_UART_IRDA;
-            
-            /* Set the base address for this UART. */
-            uart->base_address = SD_UART_IRDA_BASE;
-        }
-    }
-    else
-
-    /************** End Port Specific Section **************/
-
-        /* Not a supported port. */
-        status = NU_INVALID_COM_PORT;
-
-#ifdef GRAFIX_MOUSE
-    if ((uart->communication_mode == SERIAL_MODE) ||
-        (uart->communication_mode == SERIAL_MOUSE))
-#else
-    if (uart->communication_mode == SERIAL_MODE)
-#endif
-
-    {
-        /* Make sure the port was valid and the LISR was
-           registered. Then create the semaphore used to make
-           the SD_Put_String service thread safe. */
-        if (status == NU_SUCCESS)
-        {
-            /* Allocate memory for the semaphore control block. */
-           status = NU_Allocate_Memory(&System_Memory,(VOID**) &uart->sd_semaphore,
-                        sizeof(NU_SEMAPHORE), NU_NO_SUSPEND);
-
-#if 0
-/* original code */
-            for(tInt=0; tInt < sizeof(NU_SEMAPHORE); tInt++)
-                       /* Fixed SPR 211.  Changed type from (UINT32) to (CHAR *) */
-                       SD_OUTBYTE((CHAR *) uart->sd_semaphore + tInt, 0x00);
-#else
-	    bzero(uart->sd_semaphore, sizeof(NU_SEMAPHORE));
-#endif
-
-            if (status == NU_SUCCESS)
-            {
-                /* Build the name. */
-                sem_name[0] = 's';
-                sem_name[1] = 'e';
-                sem_name[2] = 'r';
-                sem_name[3] = 'i';
-                sem_name[4] = 'a';
-                sem_name[5] = 'l';
-                sem_name[6] = '_';
-                sem_name[7] = (CHAR)(0x30 + num_ports);
-
-                status = NU_Create_Semaphore (uart->sd_semaphore, sem_name,
-                                              1, NU_FIFO);
-            }                                   
-        }
-
-        /* Make sure all the above was completed. Then store off this
-           UART stucture and initialize the chip. */
-        if (status == NU_SUCCESS)
-        {
-            SDC_Port_List[num_ports++] = uart;
-        }
-    }
-
-    if (status == NU_SUCCESS)
-    {
-        /* Allocate memory for the data buffers. PPP only requires a TX
-           buffer so the allocation will be a little different for PPP mode. */
-#ifdef GRAFIX_MOUSE
-        if ((uart->communication_mode == SERIAL_MODE) ||
-            (uart->communication_mode == SERIAL_MOUSE))
-#else
-        if (uart->communication_mode == SERIAL_MODE)
-#endif
-
-        {
-            status = NU_Allocate_Memory (&System_Memory,(VOID**) &uart->tx_buffer, 
-                         (2 * uart->sd_buffer_size), NU_NO_SUSPEND);
-
-            /* Set the RX buffer to just past the TX buffer. */
-            uart->rx_buffer = (CHAR *)(uart->tx_buffer + uart->sd_buffer_size);
-        }
-        else
-        {
-            status = NU_Allocate_Memory (&System_Memory,(VOID**) &uart->tx_buffer, 
-                         uart->sd_buffer_size, NU_NO_SUSPEND);
-        }
-
-        if (status == NU_SUCCESS)
-        {
-            /* Setup the RX SD buffer */
-            uart->rx_buffer_read = uart->rx_buffer_write = 0;
- 
-            uart->rx_buffer_status = NU_BUFFER_EMPTY;
-
-            /* Setup the TX SD buffer */
-            uart->tx_buffer_read = uart->tx_buffer_write = 0;
-            uart->tx_buffer_status = NU_BUFFER_EMPTY;
-        }
-    }
-
-    if (status == NU_SUCCESS)
-    {
-        /* Disable interrupts */
-        int_level = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);
-
-        /* Initialize the UART */
-
-        /************** Begin Port Specific Section *************/
-
-        /* Configure the Mode Definition Register */
-        /* Set the serial port to UART mode */
-        SD_OUTBYTE(uart->base_address + MDR_OFFSET, MDR_UART_MODE);
-
-        /* Reset the TX/RX FIFOs */
-        SD_OUTBYTE(uart->base_address + FCR_OFFSET, FCR_FIFO_RESET);
-
-        /* Setup baud rate */
-        SDC_Set_Baud_Rate(uart->baud_rate, uart);
-
-        /* Set the modem control register. Set DTR, RTS to output to LOW,
-           and set INT output pin to normal operating mode */ 
-        SD_OUTBYTE (uart->base_address + MCR_OFFSET, (MCR_DTR_LOW | MCR_RTS_LOW)); 
-
-        /* Setup parity, data bits, and stop bits */
-        SD_OUTBYTE (uart->base_address + LCR_OFFSET,
-                          (LCR_NO_BREAK|uart->parity|uart->data_bits|uart->stop_bits ));
-
-        /* Setup Fifo trigger level and enable FIFO */
-        SD_OUTBYTE (uart->base_address + FCR_OFFSET, 0);
-
-        /* Register the interrupt handler for the UART receiver */
-        status = NU_Register_LISR(uart->vector, SDC_LISR, &old_lisr);
-
-        if (status == NU_SUCCESS)
-        {
-            /* Enable the RX interrupts */
-            SD_OUTBYTE (uart->base_address + IER_OFFSET, IER_RX_HOLDING_REG);
-
-            if(uart->com_port == SD_UART_MODEM)
-            {
-                /* Enable the UART interrupt globally */
-		INTH_REGS.ilr_irq[IRQ_UART_MODEM] = 0x7C;
-		INTH_REGS.mask_it_reg1 &= ~(1 << IRQ_UART_MODEM);
-            }
-            else  /* Handle UART B */
-            {    
-                /* Enable the UART interrupt globally */
-		INTH_REGS.ilr_irq[IRQ_UART_IRDA] = 0x7C;
-		INTH_REGS.mask_it_reg2 &= ~(1 << (IRQ_UART_IRDA - 16));
-            }
-
-        }
-
-        /************** End Port Specific Section *************/
-
-
-        /* Initialize the error counters. */
-        uart->parity_errors   =
-        uart->frame_errors    =
-        uart->overrun_errors  = 
-        uart->busy_errors     = 
-        uart->general_errors  = 0;
-
-        /* Restore interrupts to previous level */
-        NU_Local_Control_Interrupts(int_level);
-    }
-
-    return (status);
-}
-/***************************************************************************
-* FUNCTION
-*
-*    SDC_Put_Char
-*
-* DESCRIPTION
-*
-*    This writes a character out to the serial port.
-*
-* INPUTS
-*
-*    UINT8 :   Character to to be written to the serial port.
-*    SD_PORT *     :   Serial port to send the char to.
-*
-* OUTPUTS
-*
-*    none
-*
-****************************************************************************/
-VOID  SDC_Put_Char(UINT8 ch, SD_PORT *uart)
-{
-INT         int_level;          /* old interrupt level */
-UINT32  temp_long;
-
-#ifdef GRAFIX_MOUSE
-    if ((uart->communication_mode == SERIAL_MODE) ||
-        (uart->communication_mode == SERIAL_MOUSE))
-#else
-    if (uart->communication_mode == SERIAL_MODE)
-#endif
-
-    {
-        /* If the buffer is full wait for it to empty a little. */
-        while (uart->tx_buffer_status == NU_BUFFER_FULL);
-
-        /* Disable interrupts */
-        int_level = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);
-
-        /* Check the transmit buffer status. If it has data already
-           just add this byte to the buffer. */
-         if ( uart->tx_buffer_status != NU_BUFFER_EMPTY)
-        {
-            /* Add byte to buffer. */
-            uart->tx_buffer[uart->tx_buffer_write++] = ch;
-
-            /* Check for wrap of buffer. */
-            if(uart->tx_buffer_write == uart->sd_buffer_size)
-                uart->tx_buffer_write = 0;
-          
-            /* Check for full buffer. */
-            if (uart->tx_buffer_write == uart->tx_buffer_read) 
-                uart->tx_buffer_status = NU_BUFFER_FULL;
-
-            /* Restore interrupts to previous level */
-            NU_Local_Control_Interrupts(int_level);
-        }
-        else
-        {
-            /* Otherwise send the data. */
-
-            /* Restore interrupts to previous level */
-            NU_Local_Control_Interrupts(int_level);
-
-            /* Add byte to buffer. */
-            uart->tx_buffer[uart->tx_buffer_write++] = ch;
-
-            /* Check for wrap of buffer. */
-            if(uart->tx_buffer_write == uart->sd_buffer_size)
-                uart->tx_buffer_write = 0;
-             
-            /* Set status */
-            uart->tx_buffer_status = NU_BUFFER_DATA;
-
-            /**************** Begin Port Specific Section **************/
-
-            /* Wait until the transmitter buffer is empty */
-            while (!(SD_INBYTE (uart->base_address + LSR_OFFSET) & LSR_TX_HOLD_EMPTY));
-
-            /* Transmit the character */
-            SD_OUTBYTE (uart->base_address + THR_OFFSET, ch);
-
-            /* Enable the TX interrupts */
-            temp_long = SD_INBYTE (uart->base_address + IER_OFFSET);
-            temp_long |= IER_TX_HOLDING_REG;
-            SD_OUTBYTE (uart->base_address + IER_OFFSET, temp_long);               
-
-        }
-    
-    }  /* endif mode */
-    else 
-    {
-        /* Wait until the transmitter buffer is empty */
-        while (!(SD_INBYTE (uart->base_address + LSR_OFFSET) & LSR_TX_HOLD_EMPTY));
-
-        /* Transmit the character */
-          SD_OUTBYTE (uart->base_address + THR_OFFSET, ch);
-
-#ifndef PPP_POLLED_TX
-
-            /* Enable the TX interrupts */
-            temp_long = SD_INBYTE (uart->base_address + IER_OFFSET);
-            temp_long |= IER_TX_HOLDING_REG;
-            SD_OUTBYTE (uart->base_address + IER_OFFSET, temp_long);
-                 
-#endif /* PPP_POLLED_TX */
-
-
-    }
-
-        /***************** End Port Specific Section ***************/
-
-}
-
-/***************************************************************************
-* FUNCTION
-*
-*    SDC_LISR
-*
-* DESCRIPTION
-*
-*    This is the entry function for the receive ISR that services the UART
-*    in the ARM925.
-*
-* INPUTS
-*
-*    INT         :   Interrupt vector
-*
-* OUTPUTS
-*
-*    none
-*
-****************************************************************************/
-VOID  SDC_LISR(INT vector)
-{
-
-SD_PORT         *uart;
-CHAR            receive;
-UINT8           status;
-UINT8           int_status;
-UINT8           vector_found = NU_FALSE;
-UINT8           ier_val;
-
-
-#ifdef NU_ENABLE_PPP
-DV_DEVICE_ENTRY *device;
-#endif /* NU_ENABLE_PPP */
-
-    for(receive = 0 ; (SDC_Port_List[receive] != NU_NULL) &&
-        (receive < SD_MAX_UARTS) && !vector_found ; receive++)
-    {
-        /* See if we found one. Better have since we got an interrupt
-           from one. */
-        if (SDC_Port_List[receive] -> vector == vector)
-        {
-            /* Point our local structure to it. */
-            uart = SDC_Port_List[receive];
-            vector_found = NU_TRUE;
-        }
-    }
-
-#ifdef  NU_ENABLE_PPP
-
-    /* Find the device for this interrupt */
-    if ( (device = DEV_Get_Dev_For_Vector(vector)) != NU_NULL)
-    {
-        /* Get the address of the uart structure for this device. */ 
-        uart = &((PPP_LAYER *) device->ppp_layer)->uart;
-        vector_found = NU_TRUE;    
-    }
-
-#endif /* NU_ENABLE_PPP */
-    
-    if (vector_found == NU_TRUE)
-    {
-        /**************** Begin Port Specific Section **************/
-
-        /* Get the interrupt status register value */
-        int_status = SD_INBYTE(uart->base_address + IIR_OFFSET);
-
-        /* Loop until all interrupts are processed */
-        while (!(int_status & IIR_PENDING))
-        {
-            /* Check for a receive interrupt */
-            if (((int_status & IIR_RX_LINE_STAT) ==IIR_RX_LINE_STAT) ||
-                ((int_status & IIR_RX_RDY) ==IIR_RX_RDY) ||
-                ((int_status & IIR_RX_TIMEOUT) ==IIR_RX_TIMEOUT) )
-            {
-               /* Process every character in the receive FIFO */
-                status = SD_INBYTE(uart->base_address + LSR_OFFSET);
-
-                while (status & LSR_RX_DATA_READY)
-                {
-                    /* Get character from receive FIFO */
-                    receive = SD_INBYTE (uart->base_address + RHR_OFFSET);
-
-                    /* Check if receive character has errors */
-                    if (status & (LSR_FRAMING_ERROR | LSR_PARITY_ERROR))
-                    {
-                        /* Increment parity errors if necessary */
-                        uart->parity_errors += ((status & LSR_PARITY_ERROR) == LSR_PARITY_ERROR);
-
-                        /* Increment framing errors if necessary */
-                        uart->frame_errors += ((status & LSR_FRAMING_ERROR) == LSR_FRAMING_ERROR);
-                    }
-                    else    // no framing or parity errors
-                    {
-                        /* Increment overrun errors if necessary */
-                        uart->overrun_errors += ((status & LSR_RX_DATA_READY) == LSR_RX_DATA_READY);
-
-                        /* Switch based on UART mode */
-                        switch(uart->communication_mode)
-                        {
-                            case SERIAL_MODE: 
-
-                                if (uart->rx_buffer_status != NU_BUFFER_FULL)
-                                {
-                
-                                    /* Put the character into the buffer */
-                                    uart->rx_buffer[uart->rx_buffer_write++] = receive;
-
-                                    /* Check for wrap of buffer. */
-                                    if(uart->rx_buffer_write == uart->sd_buffer_size)
-                                        uart->rx_buffer_write = 0;
-                                    
-                                    /* Set status field based on latest character */
-                                    if (uart->rx_buffer_write == uart->rx_buffer_read)
-                                        uart->rx_buffer_status = NU_BUFFER_FULL;
-                                    else
-                                        uart->rx_buffer_status = NU_BUFFER_DATA;
-                                }
-                                else
-                                    uart->busy_errors++;
-
-                            break;
-                    
-#ifdef NU_ENABLE_PPP
-                            /* call PPP processing functions */
-
-                            case MDM_NETWORK_COMMUNICATION:
-                                /* Call this devices receive routine */
-                                device->dev_receive(device);
-                            break;
-
-                            case MDM_TERMINAL_COMMUNICATION:
-                            default:
-                                MDM_Receive(device);
-                            break;
-#endif /* NU_ENABLE_PPP */
-                        } 
-                    }
-
-                    /* Check the rx buffer status again... */
-                    status = SD_INBYTE(uart->base_address + LSR_OFFSET);
-
-                }
-
-            }   // if ((status & IIR_TYPE_MASK) == IIR_Rx_Rdy)
-
-
-            int_status = SD_INBYTE(uart->base_address + IER_OFFSET);
-
-            if (int_status & IER_TX_HOLDING_REG)
-            {
-               if (uart->communication_mode == SERIAL_MODE)
-                {    
-                    /* Bump the read pointer past the byte that was just
-                       transmitted. */
-                    ++(uart->tx_buffer_read);
-                
-                    /* Check for wrap of buffer. */
-                    if(uart->tx_buffer_read == uart->sd_buffer_size)
-                        uart->tx_buffer_read = 0;
-
-                    /* Update the status. */
-                    if (uart->tx_buffer_write == uart->tx_buffer_read)
-                    {
-                       uart->tx_buffer_status = NU_BUFFER_EMPTY;
-
-                        /* Since it is now empty disable the TX interrupt! */
-                        ier_val =  SD_INBYTE(uart->base_address + IER_OFFSET);
-                        ier_val &= ~IER_TX_HOLDING_REG;
-                        SD_OUTBYTE(uart->base_address + IER_OFFSET, ier_val);
-                    }
-                    else
-                    {
-
-                        /* Wait until the transmitter buffer is empty */
-                        while (!(SD_INBYTE (uart->base_address + LSR_OFFSET) & LSR_TX_HOLD_EMPTY));
-
-                        /* Send the next byte in the queue. */
-                        SD_OUTBYTE(uart->base_address + THR_OFFSET, uart->tx_buffer[uart->tx_buffer_read]);
-                        
-                        /* Update the status. */
-                        uart->tx_buffer_status = NU_BUFFER_DATA;
-                    }
-                }
-#ifdef NU_ENABLE_PPP
-               else
-                {
-#ifndef PPP_POLLED_TX
-                   /* Check for a transmit interrupt. */
-                   /* Is there another byte in the TX buffer to send? */
-                   if (uart->tx_buffer_read != uart->tx_buffer_write)
-                   {
-                        /* Wait until the transmitter buffer is empty */
-                        while (!(SD_INBYTE (uart->base_address + LSR_OFFSET) & LSR_TX_HOLD_EMPTY));
-
-                        /* Send the next byte in the queue. */
-                        SD_OUTBYTE (uart->base_address + THR_OFFSET, uart->tx_buffer[uart->tx_buffer_read++]); 
-                        
-                        /* Check for wrap of buffer. */
-                        uart->tx_buffer_read %= uart->sd_buffer_size;
-                   }
-                   else
-                   {
-                   
-                        /* Since it is now empty disable the TX interrupt! */
-                        ier_val =  SD_INBYTE (uart->base_address + IER_OFFSET);
-                        ier_val &= ~IER_TX_HOLDING_REG;
-                        SD_OUTBYTE (uart->base_address + IER_OFFSET, ier_val);
-
-                       /* Only activate the HISR if we are tranmitting
-                          network data. */
-                       if (uart->communication_mode == MDM_NETWORK_COMMUNICATION)
-                       {
-                            /* Add this device to the list of PPP devices that have finished
-                               sending a packet. */
-                            _ppp_tx_dev_ptr_queue [_ppp_tx_dev_ptr_queue_write++] = device;
-
-                            /* Activate the HISR that will take care of processing the
-                               next packet in queue, if one is ready. */
-                            NU_Activate_HISR (&PPP_TX_HISR);
-
-                            /* Check for wrap of ring buffer. */
-                
-                            _ppp_tx_dev_ptr_queue_write %= PPP_MAX_TX_QUEUE_PTRS;
-
-                       }
-                    }
-#endif /* PPP_POLLED_TX */
-                }
-#endif /* NU_ENABLE_PPP */
-            }
-
-            /* Get the interrupt status register value */
-            int_status = SD_INBYTE(uart->base_address + IIR_OFFSET);
-        }
-        
-        /**************** End Port Specific Section **************/
-    
-        /* No port is associated with the vector */
-    }
-    else 
-    {
-        ERC_System_Error(NU_UNHANDLED_INTERRUPT);
-    }   
-}
-
-/****************************************************************************
-* FUNCTION
-*
-*    SDC_Set_Baud_Rate
-*
-* DESCRIPTION
-*
-*    This function sets the UART buad rate.
-*
-* INPUTS
-*
-*    UINT32      :  The new baud rate.
-*    SD_PORT *     :  Serial port to set the baud rate.
-*
-* OUTPUTS
-*
-*    none
-*
-****************************************************************************/
-VOID  SDC_Set_Baud_Rate(UINT32 baud_rate, SD_PORT *uart)
-{
-    UNSIGNED    baud_div;
-    UINT32      temp_long;
-
-    /**************** Begin Port Specific Section **************/
-
-    /* Write to the divisor latch bit to enable the DLH and DLL registers */
-    temp_long = SD_INBYTE(uart->base_address + LCR_OFFSET);
-    SD_OUTBYTE (uart->base_address + LCR_OFFSET, LCR_DIV_EN);             
-
-    /* Set the baud rate */
-    baud_div = 115200 * 7 / uart->baud_rate;
-
-    /* Put LSB in DLL Reg */
-    SD_OUTBYTE (uart->base_address + DLL_OFFSET, baud_div);
-
-    /* Put MSB in DLH Reg */    
-    SD_OUTBYTE (uart->base_address + DLH_OFFSET, (baud_div >> 8));
-
-    /* Disable the Divisor Latch bit */
-    SD_OUTBYTE (uart->base_address + LCR_OFFSET, temp_long & ~LCR_DIV_EN);             
-   /**************** End Port Specific Section ****************/
-
-}
-/****************************************************************************
-* FUNCTION
-*
-*    SDC_Get_Char
-*
-* DESCRIPTION
-*
-*    This function reads the last received character from the UART.
-*
-* INPUTS
-*
-*    SD_PORT *      :   Serial port to get the char from.
-*
-* OUTPUTS
-*
-*    CHAR  :  Character read
-*
-****************************************************************************/
-CHAR  SDC_Get_Char(SD_PORT *uart)
-{
-    CHAR    ch = NU_NULL;
-
-#ifdef GRAFIX_MOUSE
-    if ((uart->communication_mode == SERIAL_MODE) ||
-        (uart->communication_mode == SERIAL_MOUSE))
-#else
-    if (uart->communication_mode == SERIAL_MODE)
-#endif
-
-    {
-        if ((uart->rx_buffer_status == NU_BUFFER_FULL) ||
-            (uart->rx_buffer_status == NU_BUFFER_DATA))
-        {
-            /* Store the character to be returned */
-            ch = uart->rx_buffer[uart->rx_buffer_read++]; 
-
-            /* If read pointer is at end, wrap it around */
-            if (uart->rx_buffer_read == uart->sd_buffer_size)
-                uart->rx_buffer_read = 0;
-
-            /* Set the status to reflect removal of the character */
-            if (uart->rx_buffer_write == uart->rx_buffer_read)
-                uart->rx_buffer_status = NU_BUFFER_EMPTY;
-            else
-                uart->rx_buffer_status = NU_BUFFER_DATA;
-        }
-
-        return (ch);
-    } /* endif mode */
-
-#ifdef NU_ENABLE_PPP
-    else if (uart->communication_mode == MDM_TERMINAL_COMMUNICATION || 
-             uart->communication_mode == MDM_NETWORK_COMMUNICATION)
-
-    /**************** Begin Port Specific Section **************/
-
-             return ((UINT8)SD_INBYTE (uart->base_address + RHR_OFFSET));
-
-    /**************** End Port Specific Section ****************/
-
-#endif /* NU_ENABLE_PPP */
-
-    /* Execution should never reach this point, this return was added
-       in response to the 'implicit return' compiler warning */
-
-    return (ch);
-}
-
-/****************************************************************************
-* FUNCTION
-*
-*    SDC_Carrier
-*
-* DESCRIPTION
-*
-*    This function checks for a carrier.
-*
-* INPUTS
-*
-*    none
-*
-* OUTPUTS
-*
-*    STATUS    :  The status of the detection.
-*
-****************************************************************************/
-STATUS SDC_Carrier(SD_PORT *uart)
-{
-    return (NU_TRUE);
-}
-
-/****************************************************************************
- Note: All functions below this point are generic and should not require
-       any changes to support other UARTS.
- ****************************************************************************/
-
-/****************************************************************************
-* FUNCTION
-*
-*    SDC_Put_String
-*
-* DESCRIPTION
-*
-*    This writes a null-terminated string out to the serial port.
-*
-* INPUTS
-*
-*    CHAR *        :   String to be written to the serial port.
-*    SD_PORT *     :   Serial port to send the string to.
-*
-* OUTPUTS
-*
-*    none
-*
-****************************************************************************/
-VOID SDC_Put_String(CHAR *str, SD_PORT *uart)
-{
-
-   /* Grab the semaphore so that strings between threads
-       do not get mixed. */
-    if (NU_Obtain_Semaphore(uart->sd_semaphore, NU_SUSPEND) == NU_SUCCESS)
-    {
-
-        /* Send out the string. */
-        for (; *str != 0; str++)
-            SDC_Put_Char(*str, uart);
-
-        /* Allow other threads to use this service. */
-        NU_Release_Semaphore (uart->sd_semaphore);
-    }
-
-}
-
-
-/****************************************************************************
-* FUNCTION
-*
-*    SDC_Data_Ready
-*
-* DESCRIPTION
-*
-*    This function checks to see if there are any characters in the
-*    receive buffer.  A status value is returned indicating whether
-*    characters are present in the receive buffer.
-*
-* INPUTS
-*
-*    SD_PORT *      :   Serial port to check for data.
-*
-* OUTPUTS
-*
-*    STATUS                                The status indicates the
-*                                          presence of characters.
-*
-****************************************************************************/
-STATUS SDC_Data_Ready(SD_PORT *port)
-{
-    /* Check the status. */
-    if((port->rx_buffer_status == NU_BUFFER_FULL) ||
-       (port->rx_buffer_status == NU_BUFFER_DATA))
-
-        return (NU_TRUE);
-
-    else
-
-        return (NU_FALSE);
-}
-
-/****************************************************************************
-* FUNCTION
-*
-*    SDC_Change_Communication_Mode
-*
-* DESCRIPTION
-*
-*    This function switches the serial port between terminal mode and
-*    network mode.  The mode affects how incoming characters are directed.
-*
-* INPUTS
-*
-*    INT      :  The mode of operation desired.
-*
-* OUTPUTS
-*
-*    none
-*
-****************************************************************************/
-VOID SDC_Change_Communication_Mode(INT mode, SD_PORT *uart)
-{
-    uart->communication_mode = mode;
-
-} /* SDC_Change_Communication_Mode */
-
-/****************************************************************************
-* FUNCTION
-*
-*    SDC_Reset
-*
-* DESCRIPTION
-*
-*    This function intializes the data variables associated with a UART
-*
-* INPUTS
-*
-*    SD_PORT      * :   Serial port to reset
-*
-* OUTPUTS
-*
-*    STATUS      :   Returns URT_SUCCESS if successful initialization,
-*                    else a negative value is returned.
-*
-****************************************************************************/
-VOID SDC_Reset (SD_PORT *uart)
-{
-    /* Ini the error counters */
-    uart->frame_errors   = 0;
-    uart->overrun_errors = 0;
-    uart->parity_errors  = 0;
-    uart->busy_errors    = 0;
-    uart->general_errors = 0;
-}
-
-/***************************************************************************
-* FUNCTION
-*
-*    URT_Init_Port
-*
-* DESCRIPTION
-*
-*    This function intializes the data variables associated with a UART
-*
-* INPUTS
-*
-*    SD_PORT      * :   Serial port to reset
-*
-* OUTPUTS
-*
-*    STATUS      :   Returns URT_SUCCESS if successful initialization,
-*                    else a negative value is returned.
-*
-****************************************************************************/
-#ifdef NU_ENABLE_PPP
-STATUS  URT_Init_Port(DV_DEVICE_ENTRY *device)
-{
-    SD_PORT   *uart;
-    STATUS    ret_status;
-
-    /* Get a pointer to the UART layer of this device. */
-    uart = &((PPP_LAYER *) device->ppp_layer)->uart;
-
-    /* Init the serial port, copy init parameters from the device 
-       structure. */
-    uart->com_port              = device->dev_com_port;
-    uart->baud_rate             = device->dev_baud_rate;
-    uart->data_bits             = device->dev_data_bits;
-    uart->stop_bits             = device->dev_stop_bits;
-    uart->parity                = device->dev_parity;
-    uart->data_mode             = device->dev_data_mode;
-    uart->vector                = device->dev_vect;
-    uart->driver_options        = device->dev_driver_options;
-    uart->communication_mode    = MDM_TERMINAL_COMMUNICATION;
-    uart->sd_buffer_size        = (2 * (PPP_MTU + PPP_FCS_SIZE + 
-                                    PPP_MAX_PROTOCOL_SIZE + PPP_MAX_ADDR_CONTROL_SIZE));
-
-    /* Init the port */
-    ret_status = NU_SD_Init_Port (uart);
-
-    if (ret_status == NU_SUCCESS)
-    {
-        /* Copy the vector back into the device entry just in case
-           the UART driver changed it. */
-        device->dev_vect = uart->vector;
-    }
-
-    return (ret_status);
-
-}
-#endif /* NU_ENABLE_PPP */
--- a/nuc-fw/nucleus/tmcal.c	Mon Nov 11 09:56:23 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-/*
- * FreeNucleus port by Spacefalcon the Outlaw
- *
- * This module implements the INT_Timer_Initialize() function
- * for the proof-of-concept Calypso port.
- *
- * TIMER2 configuration is based on that used by OsmocomBB.
- */
-
-#include "calirq.h"
-#include "caltimer.h"
-
-void
-INT_Timer_Initialize()
-{
-	/* program the timer */
-	TIMER2_REGS.cntl = CNTL_CLOCK_ENABLE;
-	TIMER2_REGS.load = 4062;
-	TIMER2_REGS.cntl = CNTL_CLOCK_ENABLE | CNTL_AUTO_RELOAD | CNTL_START;
-	/* now let it interrupt */
-	INTH_REGS.ilr_irq[IRQ_TIMER2] = 0x7E;
-	INTH_REGS.mask_it_reg1 &= ~(1 << IRQ_TIMER2);
-}