diff src/cs/os/nucleus/tct.s @ 0:92470e5d0b9e

src: partial import from FC Selenite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 15 May 2020 01:28:16 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cs/os/nucleus/tct.s	Fri May 15 01:28:16 2020 +0000
@@ -0,0 +1,3073 @@
+;/*************************************************************************/
+;/*                                                                       */
+;/*        Copyright (c) 1993-1994 Accelerated Technology, Inc.           */
+;/*                                                                       */
+;/* PROPRIETARY RIGHTS of Accelerated Technology are involved in the      */
+;/* subject matter of this material.  All manufacturing, reproduction,    */
+;/* use, and sales rights pertaining to this subject matter are governed  */
+;/* by the license agreement.  The recipient of this software implicitly  */
+;/* accepts the terms of the license.                                     */
+;/*                                                                       */
+;/*************************************************************************/
+;
+;/*************************************************************************/
+;/*                                                                       */
+;/* FILE NAME                                            VERSION          */
+;/*                                                                       */
+;/*      tct.s                                       PLUS/THUMB/T 1.2     */
+;/*                                                                       */
+;/* COMPONENT                                                             */
+;/*                                                                       */
+;/*      TC - Thread Control                                              */
+;/*                                                                       */
+;/* DESCRIPTION                                                           */
+;/*                                                                       */
+;/*      This file contains the target processor dependent routines for   */
+;/*      performing target-dependent scheduling functions.                */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* DATA STRUCTURES                                                       */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* 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. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*	 B. Sellew	 04-19-1996	 Added saving and restoring of    */
+;/*					   v5, v6, and ip, resulting in   */
+;/*					   version 1.2 (spr103)		  */
+;/*	 P. Roussel (TI) 07-21-1999	 Modified TCT_Schedule for GSM    */
+;/*					 small sleep implementation    	  */
+;/*                                                                       */
+;/*************************************************************************/
+;#define         NU_SOURCE_FILE
+;
+;#include        "cs_extr.h"                 /* Common service functions  */
+;#include        "tc_extr.h"                 /* Thread control functions  */
+;
+;/* Define constants used in low-level initialization.  */
+;
+;
+LOCKOUT         .equ     00C0h              ; Interrupt lockout value
+LOCK_MSK        .equ     00C0h              ; Interrupt lockout mask value
+MODE_MASK       .equ     001Fh              ; Processor Mode Mask
+SUP_MODE        .equ     0013h              ; Supervisor Mode (SVC)
+IRQ_MODE        .equ     0012h              ; Interrupt Mode (IRQ)
+FIQ_MODE        .equ     0011h              ; Fast Interrupt Mode (FIQ)
+;
+;
+;
+;/* Define a variable for saving the system stack limit in.  This value is
+;   intialized in INT.S and is in effect whenever the system stack is in 
+;   use.  */
+;
+;VOID    *TCT_System_Limit;
+;
+;/* Define internal variables so the C compiler can provide meaningful 
+;   code with offsets into data structures.  Typically, this section is
+;   removed after this file is compiled down to assembly language.  */
+;   
+;BYTE_PTR        REG_Stack_Base;
+;BYTE_PTR        REG_Stack_End;
+;BYTE_PTR        REG_Stack_Ptr;
+;UNSIGNED        REG_Stack_Size;
+;TC_TCB         *REG_Thread_Ptr;
+;TC_HCB         *REG_HISR_Ptr;
+;TC_PROTECT     *REG_Protect_Ptr;
+;VOID           *REG_Function_Ptr;
+;
+        .def   _TCT_System_Limit
+        .bss   _TCT_System_Limit, 4, 4
+;
+;
+        .text
+;
+;/* Define external inner-component global data references.  */
+;
+;extern TC_TCB          *TCD_Execute_Task;
+;extern TC_HCB          *TCD_Execute_HISR;
+;extern VOID            *TCD_Current_Thread;
+;extern VOID            *TCD_System_Stack;
+;extern INT              TCD_Interrupt_Count;
+;extern TC_HCB          *TCD_Active_HISR_Heads[TC_HISR_PRIORITIES];
+;extern TC_HCB          *TCD_Active_HISR_Tails[TC_HISR_PRIORITIES];
+;extern INT              TCD_Interrupt_Level;
+;extern UNSIGNED         TMD_Time_Slice;
+;extern INT              TMD_Time_Slice_State;
+;
+        .ref    _TCD_Execute_Task
+        .ref    _TCD_Execute_HISR
+        .ref    _TCD_Current_Thread
+        .ref    _TCD_System_Stack
+        .ref    _TCD_Interrupt_Count
+        .ref    _TCD_Active_HISR_Heads
+        .ref    _TCD_Active_HISR_Tails
+        .ref    _TCD_Interrupt_Level
+        .ref    _TMD_Time_Slice
+        .ref    _TMD_Time_Slice_State
+;
+;
+;/* Define external function references.  */
+;VOID    TCC_Task_Shell(VOID);
+;VOID    TCC_Signal_Shell(VOID);
+;VOID    TCT_HISR_Shell(VOID);
+;VOID    ERC_System_Error(INT error);
+;
+        .ref    $TCC_Task_Shell
+        .ref    $TCC_Signal_Shell
+        .ref    $ERC_System_Error
+	.ref	IND_CALL
+;
+;/* Define internal function references.  */
+;VOID  TCT_Schedule_Protected(VOID *thread);
+;
+        .def    _TCT_Schedule_Protected
+;
+;
+;/*************************************************************************/
+;/*                                                                       */
+;/* 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.                   */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* CALLED BY                                                             */
+;/*                                                                       */
+;/*      Application                                                      */
+;/*                                                                       */
+;/* CALLS                                                                 */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* INPUTS                                                                */
+;/*                                                                       */
+;/*      new_level                           New interrupt enable level   */
+;/*                                                                       */
+;/* OUTPUTS                                                               */
+;/*                                                                       */
+;/*      old_level                           Previous interrupt enable    */
+;/*                                            level                      */
+;/*                                                                       */
+;/* HISTORY                                                               */
+;/*                                                                       */
+;/*         NAME            DATE                    REMARKS               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;INT TCT_Control_Interrupts (INT new_level)
+;{
+	.def	$TCT_Control_Interrupts
+$TCT_Control_Interrupts			    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Control_Interrupts
+;
+        .def    _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     a3,CPSR                     ; Pickup current CPSR
+        ORR     a3,a3,#LOCKOUT              ; Build lockout CPSR
+        MSR     CPSR,a3                     ; Lockout interrupts temporarily
+        LDR     a2,Int_Level	            ; Pickup interrupt level
+        LDR     a4,[a2, #0]                 ; Pickup current interrupt lockout
+        BIC     a3,a3,#LOCK_MSK             ; Clear lockout mask
+        ORR     a3,a3,a1                    ; Build new CPSR with appropriate
+                                            ;   interrupts locked out
+        STR     a1,[a2,#0]                  ; Save current lockout 
+        MSR     CPSR,a3                     ; Setup new CPSR lockout bits
+        MOV     a1,a4                       ; Return previous lockout
+        BX      lr                          ; Return to caller
+;}    
+;
+;
+;
+;/*************************************************************************/
+;/*                                                                       */
+;/* FUNCTION                                                              */
+;/*                                                                       */
+;/* TCT_Local_Control_Interrupts                                          */
+;/*                                                                       */
+;/* DESCRIPTION                                                           */
+;/*                                                                       */
+;/*      This function enables and disables interrupts as specified by    */
+;/*      the caller.                                                      */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* CALLED BY                                                             */
+;/*                                                                       */
+;/*      Application                                                      */
+;/*                                                                       */
+;/* CALLS                                                                 */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* INPUTS                                                                */
+;/*                                                                       */
+;/*      new_level                           New interrupt enable level   */
+;/*                                                                       */
+;/* OUTPUTS                                                               */
+;/*                                                                       */
+;/*      old_level                           Previous interrupt enable    */
+;/*                                            level                      */
+;/*                                                                       */
+;/* HISTORY                                                               */
+;/*                                                                       */
+;/*         NAME            DATE                    REMARKS               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;INT TCT_Local_Control_Interrupts (INT new_level)
+;{
+	.def	$TCT_Local_Control_Interrupts
+$TCT_Local_Control_Interrupts		    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Local_Control_Interrupts
+;
+        .def    _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     a3,CPSR                     ; Pickup current CPSR
+        MOV     a4,a3                       ; 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     a3,a3,#LOCK_MSK             ; Clear all current interrupts
+        ORR     a3,a3,a1                    ; Build new CPSR with new
+                                            ;   interrupt level
+        MSR     CPSR,a3                     ; Setup new CPSR interrupt bits
+;
+;    /* Return old interrupt lockout level.  */
+;    return(old_level);
+;
+        MOV     a1,a4                       ; Return previous lockout
+        BX      lr                          ; Return to caller
+;}    
+;
+;
+;
+;/*************************************************************************/
+;/*                                                                       */
+;/* FUNCTION                                                              */
+;/*                                                                       */
+;/*  TCT_Restore_Interrupts                                               */
+;/*                                                                       */
+;/* DESCRIPTION                                                           */
+;/*                                                                       */
+;/*      This function restores interrupts to that specified in the global*/
+;/*      TCD_Interrupt_Level variable.                                    */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* CALLED BY                                                             */
+;/*                                                                       */
+;/*      Application                                                      */
+;/*                                                                       */
+;/* CALLS                                                                 */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* INPUTS                                                                */
+;/*                                                                       */
+;/*      None.                                                            */
+;/*                                                                       */
+;/* OUTPUTS                                                               */
+;/*                                                                       */
+;/*      None.                                                            */
+;/*                                                                       */
+;/* HISTORY                                                               */
+;/*                                                                       */
+;/*         NAME            DATE                    REMARKS               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;VOID TCT_Restore_Interrupts  (VOID)
+;{
+	.def	$TCT_Restore_Interrupts
+$TCT_Restore_Interrupts			    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Restore_Interrupts
+;
+        .def    _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     a2,CPSR                     ; Pickup current CPSR
+        MOV     a3,a2                       ; save the CPSR value
+        ORR     a2,a2,#LOCKOUT              ; Build lockout CPSR
+        MSR     CPSR,a2                     ; Lockout interrupts temporarily
+        BIC     a3,a3,#LOCK_MSK             ; Clear current interrupt levels
+        LDR     a2,Int_Level	            ; Load address of TCD_Interrupt_Level
+        LDR     a1,[a2, #0]                 ; Pickup current interrupt lockout
+        ORR     a3,a3,a1                    ; Build new CPSR with appropriate
+                                            ;   interrupts locked out
+        MSR     CPSR,a3                     ; Setup new CPSR lockout bits
+        BX      lr                          ; 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.                                                           */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* 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               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;VOID  TCT_Build_Task_Stack(TC_TCB *task)
+;{
+	.def	$TCT_Build_Task_Stack
+$TCT_Build_Task_Stack			    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Build_Task_Stack
+;
+        .def    _TCT_Build_Task_Stack
+_TCT_Build_Task_Stack
+;
+;    /* Pickup the stack base.  */
+;    REG_Stack_Base =  (BYTE_PTR) task -> tc_stack_start;
+;    
+        LDR     a3,[a1,#24h]                ; Pickup the stack starting address
+;
+;    /* Pickup the stack size.  */
+;    REG_Stack_Size =  task -> tc_stack_size;
+;    
+        LDR     a2,[a1,#30h]                ; Pickup the stack size in bytes
+;
+;    /* Calculate the stack ending address.  */
+;    REG_Stack_End =  REG_Stack_Base + REG_Stack_Size - 1;
+;
+        ADD     a4,a2,a3                    ; Compute the beginning of stack
+        BIC     a4,a4,#3                    ; Insure word alignment
+        SUB     a4,a4,#4                    ; Reserve a word
+;
+;    /* Save the stack ending address.  */
+;    task -> tc_stack_end =  REG_Stack_End;
+;    
+        STR     a4,[a1,#28h]                ; 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
+;                                               a1      Saved a1
+;                                               a2      Saved a2
+;                                               a3      Saved a3
+;                                               a4      Saved a4
+;                                               v1      Saved v1
+;                                               v2      Saved v2
+;                                               v3      Saved v3
+;                                               v4      Saved v4
+;						v5	Saved v5
+;						v6	Saved v6
+;                                               v7      Saved v7
+;                                               v8      Saved v8
+;						ip	Saved ip
+;                                               sp      Saved sp
+;                                               lr      Saved lr
+;               (Higher Address) Stack Bottom-> pc      Saved pc
+;    */
+;
+        LDR     a3,Task_Shell		    ; Pickup address of shell entry
+        STR     a3,[a4], #-4                ; Store entry address on stack
+        MOV     a3,#0                       ; Clear value for initial registers
+        STR     a3,[a4], #-4                ; Store initial lr
+        ADD     a3,a4,#8h                   ; Compute initial sp
+        STR     a3,[a4], #-4                ; Store initial sp (Stack Bottom)
+	STR	ip,[a4], #-4		    ; Store ip
+        STR     a3,[a4], #-4                ; Store initial v8
+        LDR     a3,[a1,#24h]                ; Pickup the stack starting address
+        STR     a3,[a4], #-4                ; Store initial v7
+        MOV     a3,#0                       ; Clear value for initial registers
+	STR	v6,[a4], #-4		    ; Store v6
+	STR	v5,[a4], #-4		    ; Store v5
+        STR     a3,[a4], #-4                ; Store initial v4
+        STR     a3,[a4], #-4                ; Store initial v3
+        STR     a3,[a4], #-4                ; Store initial v2
+        STR     a3,[a4], #-4                ; Store initial v1
+        STR     a3,[a4], #-4                ; Store initial a4
+        STR     a3,[a4], #-4                ; Store initial a3
+        STR     a3,[a4], #-4                ; Store initial a2
+        STR     a3,[a4], #-4                ; Store initial a1
+        MSR     CPSR_FLG,a3                 ; Clear the flags
+        MRS     a3,CPSR                     ; Pickup the CPSR
+        BIC     a3,a3,#LOCK_MSK             ; Clear initial interrupt lockout
+	ORR	a3,a3,#20h		    ; Set to Thumb state
+        STR     a3,[a4], #-4                ; Store CPSR on the initial stack
+        MOV     a3,#1                       ; Build interrupt stack type (1)
+        STR     a3,[a4, #0]                 ; Store stack type on the top 
+;    
+;    /* Save the minimum amount of remaining stack memory.  */
+;    task -> tc_stack_minimum =  REG_Stack_Size - 72;
+;    
+        MOV     a3,#72                      ; Size of interrupt stack frame
+        SUB     a2,a2,a3                    ; Compute minimum available bytes
+        STR     a2,[a1, #34h]               ; Save in minimum stack area
+;
+;    /* Save the new stack pointer into the task's control block.  */
+;    task -> tc_stack_pointer =  (VOID *) Stack_Top;
+;
+        STR     a4,[a1, #2Ch]               ; Save stack pointer
+        BX      lr
+;}
+;
+;
+;
+;/*************************************************************************/
+;/*                                                                       */
+;/* FUNCTION                                                              */
+;/*                                                                       */
+;/*      TCT_Build_HISR_Stack                                             */
+;/*                                                                       */
+;/* DESCRIPTION                                                           */
+;/*                                                                       */
+;/*      This function builds an HISR stack frame that allows quick       */
+;/*      scheduling of the HISR.                                          */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* CALLED BY                                                             */
+;/*                                                                       */
+;/*      TCC_Create_HISR                     Create HISR function         */
+;/*                                                                       */
+;/* CALLS                                                                 */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* INPUTS                                                                */
+;/*                                                                       */
+;/*      hisr                                HISR control block pointer   */
+;/*                                                                       */
+;/* OUTPUTS                                                               */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* HISTORY                                                               */
+;/*                                                                       */
+;/*         NAME            DATE                    REMARKS               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;VOID  TCT_Build_HISR_Stack(TC_HCB *hisr)
+;{
+	.def	$TCT_Build_HISR_Stack
+$TCT_Build_HISR_Stack			    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Build_HISR_Stack
+;
+        .def    _TCT_Build_HISR_Stack
+_TCT_Build_HISR_Stack
+;
+;    /* Pickup the stack base.  */
+;    REG_Stack_Base =  (BYTE_PTR) hisr -> tc_stack_start;
+;    
+        LDR     a3,[a1,#24h]                ; Pickup the stack starting address
+;
+;    /* Pickup the stack size.  */
+;    REG_Stack_Size =  hisr -> tc_stack_size;
+;    
+        LDR     a2,[a1,#30h]                ; Pickup the stack size in bytes
+;
+;    /* Calculate the stack ending address.  */
+;    REG_Stack_End =  REG_Stack_Base + REG_Stack_Size;
+;    
+        ADD     a4,a2,a3                    ; Compute the beginning of stack
+        BIC     a4,a4,#3                    ; Insure word alignment
+        SUB     a4,a4,#4                    ; Reserve a word
+;
+;    /* Save the stack ending address.  */
+;    hisr -> tc_stack_end =  REG_Stack_End;
+;    
+        STR     a4,[a1,#28h]                ; 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)
+;						0/0x20  Saved state mask
+;                                               v1      Saved v1
+;                                               v2      Saved v2
+;                                               v3      Saved v3
+;                                               v4      Saved v4
+;						v5	Saved v5
+;						v6	Saved v6
+;                                               v7   	Saved v7
+;                                               v8      Saved v8
+;						ip	Saved ip
+;               (Higher Address) Stack Bottom-> pc      Saved pc
+;    */
+;
+        LDR     a3,HISR_Shell		    ; Pickup address of shell entry
+        STR     a3,[a4], #-4                ; Store entry address on stack
+        ADD     a3,a4,#4h                   ; Compute initial sp
+	STR	ip,[a4], #-4		    ; Store ip
+        STR     a3,[a4], #-4                ; Store initial v8
+        LDR     a3,[a1,#24h]                ; Pickup the stack starting address
+        STR     a3,[a4], #-4                ; Store initial v7
+        MOV     a3,#0                       ; Clear value for initial registers
+	STR	v6,[a4], #-4		    ; Store v6
+	STR	v5,[a4], #-4		    ; Store v5
+        STR     a3,[a4], #-4                ; Store initial v4
+        STR     a3,[a4], #-4                ; Store initial v3
+        STR     a3,[a4], #-4                ; Store initial v2
+        STR     a3,[a4], #-4                ; Store initial v1
+	STR	a3,[a4], #-4		    ; Store initial state mask
+        STR     a3,[a4, #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 - 44;
+;        
+        MOV     a3,#44                      ; Size of solicited stack frame
+        SUB     a2,a2,a3                    ; Compute minimum available bytes
+        STR     a2,[a1, #34h]               ; Save in minimum stack area
+;
+;    /* Save the new stack pointer into the task's control block.  */
+;    hisr -> tc_stack_pointer =  (VOID *) Stack_Top;
+;
+        STR     a4,[a1, #2Ch]               ; Save stack pointer
+        BX      lr                          ; 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.                                            */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* CALLED BY                                                             */
+;/*                                                                       */
+;/*      TCC_Send_Signals                    Send signals to a task       */
+;/*                                                                       */
+;/* CALLS                                                                 */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* INPUTS                                                                */
+;/*                                                                       */
+;/*      task                                Task control block pointer   */
+;/*                                                                       */
+;/* OUTPUTS                                                               */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* HISTORY                                                               */
+;/*                                                                       */
+;/*         NAME            DATE                    REMARKS               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;VOID  TCT_Build_Signal_Frame(TC_TCB *task)
+;{
+	.def	$TCT_Build_Signal_Frame
+$TCT_Build_Signal_Frame			    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Build_Signal_Frame
+;
+        .def    _TCT_Build_Signal_Frame
+_TCT_Build_Signal_Frame
+;
+;    /* Pickup the stack pointer.  */
+;    REG_Stack_Ptr =  (BYTE_PTR) task -> tc_stack_pointer;
+;    
+        LDR     a4,[a1,#2ch]                ; 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)
+;						0/0x20  Saved state mask
+;                                               v1      Saved v1
+;                                               v2      Saved v2
+;                                               v3      Saved v3
+;                                               v4      Saved v4
+;						v5	Saved v5
+;						v6	Saved v6
+;                                               v7   	Saved v7
+;                                               v8      Saved v8
+;						ip	Saved ip
+;               (Higher Address) Stack Bottom-> pc      Saved pc
+;    */
+;
+        LDR     a3,Signal_Shell		    ; Pickup address of shell entry
+        STR     a3,[a4], #-4                ; Store entry address on stack
+        ADD     a3,a4,#4h                   ; Compute initial sp
+	STR	ip,[a4], #-4		    ; Store ip
+        STR     a3,[a4], #-4                ; Store initial v8
+        LDR     a3,[a1,#24h]                ; Pickup the stack starting address
+        STR     a3,[a4], #-4                ; Store initial v7
+        MOV     a3,#0                       ; Clear value for initial registers
+	STR	v6,[a4], #-4		    ; Store v6
+	STR	v5,[a4], #-4		    ; Store v5
+        STR     a3,[a4], #-4                ; Store initial v4
+        STR     a3,[a4], #-4                ; Store initial v3
+        STR     a3,[a4], #-4                ; Store initial v2
+        STR     a3,[a4], #-4                ; Store initial v1
+	MOV	a2,#20h			    ; Get initial state mask
+	STR	a2,[a4, #0]		    ; Store initial state mask
+        STR     a3,[a4, #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     a4,[a1, #2Ch]               ; Save stack pointer
+        BX      lr                          ; 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.                                           */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* 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               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;UNSIGNED  TCT_Check_Stack(void)
+;{
+	.def	$TCT_Check_Stack
+$TCT_Check_Stack			    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Check_Stack
+;
+        .def    _TCT_Check_Stack
+_TCT_Check_Stack
+;
+;TC_TCB         *thread;
+;UNSIGNED       remaining;
+;
+;    /* Pickup the current task/HISR pointer.  */
+;    thread =  (TC_TCB *) TCD_Current_Thread;
+;
+        LDR     a1,Current_Thread	    ; Pickup address of thread pointer
+        LDR     a1,[a1,#0]                  ; Pickup thread pointer
+;
+;    /* Determine if there is a current thread.  */
+;    if (thread)
+;    {
+;
+        CMP     a1,#0                       ; Determine if a thread is active
+        MOV     a4,#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     a3,[a1,#24h]                ; Pickup start of stack area
+        CMP     sp,a3                       ; Compare with current stack ptr
+        BLT     TCT_Stack_Range_Error       ; If less, stack is out of range
+        LDR     a2,[a1,#28h]                ; Pickup end of stack area
+        CMP     sp,a2                       ; 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     lr,[sp, #4]!                ; Store lr on the stack
+        MOV     a1,#3                       ; Build NU_STACK_OVERFLOW code
+        LDR     a4,System_Error             ; Call system error handler.  Note:
+        BX      a4                          ;   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     a4,sp,a3                    ; Calculate remaining stack size
+;
+;        /* Determine if there is enough memory on the stack to save all of the
+;           registers.  */
+;        if (remaining < 80)
+;
+        CMP     a4,#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     lr,[sp, #4]!                ; Store lr on the stack
+        MOV     a1,#3                       ; Build NU_STACK_OVERFLOW code
+        LDR     a4,System_Error             ; Call system error handler.  Note:
+        BX      a4                          ;   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     a3,[a1,#34h]
+        CMP     a4,a3
+        STRCC   a4,[a1,#34h]
+;
+;            /* 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     a1,a4                       ; Return remaining bytes
+        BX      lr                          ; Return to caller
+;}
+;
+;
+;
+;/*************************************************************************/
+;/*                                                                       */
+;/* FUNCTION                                                              */
+;/*                                                                       */
+;/*      TCC_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.                                                          */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* CALLED BY                                                             */
+;/*                                                                       */
+;/*      INC_Initialize                      Main initialization routine  */
+;/*                                                                       */
+;/* CALLS                                                                 */
+;/*                                                                       */
+;/*      TCT_Control_To_Thread               Transfer control to a thread */
+;/*      INT_Small_Sleep		     GSM small sleep              */
+;/* INPUTS                                                                */
+;/*                                                                       */
+;/*      TCD_Execute_Task                    Pointer to task to execute   */
+;/*                                                                       */
+;/* OUTPUTS                                                               */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* HISTORY                                                               */
+;/*                                                                       */
+;/*         NAME            DATE                    REMARKS               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*	 P. Roussel (TI) 07-21-1999	 Call GSM small sleep 		  */
+;/*                                                                       */
+;/*************************************************************************/
+;VOID  TCT_Schedule(void)
+;{
+	.def	$TCT_Schedule
+$TCT_Schedule				    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Schedule
+;
+        .def    _TCT_Schedule
+_TCT_Schedule
+;
+;    /* Restore interrupts according to the value contained in 
+;       TCD_Interrupt_Level.  */
+;
+        LDR     a2,Int_Level	            ; Build address of interrupt level
+        MRS     a1,CPSR                     ; Pickup current CPSR
+        LDR     a3,[a2, #0]                 ; Pickup current interrupt lockout
+        BIC     a1,a1,#LOCK_MSK             ; Clear the interrupt lockout bits
+        ORR     a1,a1,a3                    ; Build new interrupt lockout CPSR
+        MSR     CPSR,a1                     ; Setup new CPSR 
+        LDR     a3,Execute_HISR		    ; Pickup TCD_Execute_HISR address
+        LDR     a4,Execute_Task		    ; Pickup TCD_Execute_Task address
+;
+;    /* Wait until a thread (task or HISR) is available to execute.  */
+;    do
+;    {
+	.def	TCT_Schedule_Loop
+TCT_Schedule_Loop
+;
+;    } while ((!TCD_Execute_HISR) && (!TCD_Execute_Task));
+;
+        LDR     a1,[a3, #0]                 ; Pickup highest priority HISR ptr
+        CMP     a1,#0                       ; Is there a HISR active?
+        BNE     TCT_Schedule_Thread         ; Found an HISR
+        LDR     a1,[a4, #0]                 ; Pickup highest priority Task ptr
+        CMP     a1,#0                       ; Is there a task active?
+
+        .ref    INT_Small_Sleep
+        BEQ     INT_Small_Sleep		    ; No, enter the GSM Small Sleep mode
+	
+;
+;    /* Yes, either a task or an HISR is ready to execute.  Lockout 
+;       interrupts while the thread is transferred to.  */
+;
+TCT_Schedule_Thread
+        MRS     a2,CPSR                     ; Pickup CPSR again
+        ORR     a2,a2,#LOCKOUT              ; Build interrupt lockout value
+        MSR     CPSR,a2                     ; 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.                                          */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* 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               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 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     a2,Current_Thread	    ; Pickup current thread ptr address
+        LDR     a3,[a1, #1ch]               ; Pickup scheduled count
+        STR     a1,[a2, #0]                 ; Setup current thread pointer
+; TI CODE : Call the Function that log the Current Thread.
+
+  .if OP_L1_STANDALONE = 0
+    .if TI_NUC_MONITOR = 1
+  		.global _ti_nuc_monitor_Thread_log
+		STMFD	sp!,{r0-r5}
+		BL		_ti_nuc_monitor_Thread_log		; Call the Thread Log function.
+		LDMFD	sp!,{r0-r5}
+    .endif
+  .endif
+;
+;    /* Increment the thread scheduled counter.  */
+;    thread -> tc_scheduled++;
+;
+        LDR     a4,[a1, #20h]               ; Pickup time slice value
+        ADD     a3,a3,#1                    ; Increment the scheduled count
+        STR     a3,[a1, #1ch]               ; Store new scheduled count
+;
+;    /* Check for time slice option.  */
+;    if (thread -> tc_cur_time_slice)
+;    {
+        CMP     a4,#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     a3,Time_Slice		    ; Pickup address of TMD_Time_Slice
+        LDR     a2,Slice_State		    ; Pickup address of 
+                                            ;   TMD_Time_Slice_State
+        STR     a4,[a3,#0]                  ; Setup the time slice
+        MOV     a3,#0                       ; Build active state flag
+        STR     a3,[a2,#0]                  ; Set the active flag
+;    }
+TCT_No_Start_TS_1
+;
+;    /* Pickup the stack pointer and resume the thread.  */
+;    REG_Stack_Ptr =  thread -> tc_stack_pointer;
+;
+        LDR     sp,[a1, #2ch]               ; 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     a2,[sp], #4                 ; Pop off the stack type 
+        CMP     a2,#1                       ; See if it is an interrupt stack
+        BEQ     TCT_Interrupt_Resume        ; If so, an interrupt resume of
+                                            ;   thread is required
+        LDR     a2,Int_Level		    ; Pickup address of interrupt 
+                                            ;   lockout
+        MRS     a1,CPSR                     ; Pickup current CPSR
+        BIC     a1,a1,#LOCK_MSK             ; Clear lockout mask
+        LDR     a3,[a2, #0]                 ; Pickup interrupt lockout mask
+        ORR     a1,a1,a3                    ; Build new interrupt lockout mask
+	LDR	a3,[sp], #4		    ; Pop off the state mask
+	ORR	a1,a1,a3		    ; Set appropriate state
+	MSR	SPSR,a1			    ; Place in the SPSR
+        LDMIA   sp!,{v1-ip,pc}^       	    ; A solicited return is required.  
+;
+TCT_Interrupt_Resume
+        LDR     a1,[sp],#4                  ; Pop off the CPSR
+        LDR     a2,Int_Level		    ; Pickup address of interrupt 
+                                            ;   lockout
+        BIC     a1,a1,#LOCK_MSK             ; Clear lockout mask
+        LDR     a3,[a2, #0]                 ; Pickup interrupt lockout mask
+        ORR     a1,a1,a3                    ; Build new interrupt lockout mask
+	MSR	SPSR,a1			    ; Place it into the SPSR
+        LDMIA   sp,{a1-pc}^     	    ; 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.                                   */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* CALLED BY                                                             */
+;/*                                                                       */
+;/*      Other Components                                                 */
+;/*                                                                       */
+;/* CALLS                                                                 */
+;/*                                                                       */
+;/*      TCT_Schedule                        Schedule the next thread     */
+;/*                                                                       */
+;/* INPUTS                                                                */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* OUTPUTS                                                               */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* HISTORY                                                               */
+;/*                                                                       */
+;/*         NAME            DATE                    REMARKS               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;VOID  TCT_Control_To_System(void)
+;{
+	.def	$TCT_Control_To_System
+$TCT_Control_To_System			    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Control_To_System
+;
+        .def    _TCT_Control_To_System
+_TCT_Control_To_System
+;
+;    /* Lockout interrupts.  */
+;
+        MRS     a1,CPSR                     ; Pickup current CPSR
+        ORR     a1,a1,#LOCKOUT              ; Build interrupt lockout value
+        MSR     CPSR,a1                     ; Lockout interrupts
+;    
+;    /* Save a minimal context of the thread.  */
+;
+        STMDB   sp!,{v1-ip,lr}        	    ; Save minimal context of thread on
+                                            ;   the current stack
+	MOV	a3,lr			    ; Determine what state the
+	MOV	a3,a3,LSL #31   	    ;   caller was in and build an
+	MOV	a3,a3,LSR #26		    ;   appropriate state mask
+	STR	a3,[sp, #-4]!		    ; Place it on the stack
+        MOV     a3,#0                       ; Build solicited stack type value
+                                            ;   and NU_NULL value
+        STR     a3,[sp, #-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     a2,Current_Thread	    ; Pickup current thread ptr address
+        LDR     a1,[a2, #0]                 ; Pickup current thread pointer
+;
+;    /* Clear the current thread control block pointer.  */
+;    TCD_Current_Thread =  NU_NULL;
+;    
+        LDR     a4,Slice_State		    ; Pickup time slice state address
+        STR     a3,[a2, #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     a2,[a4, #0]                 ; Pickup time slice state flag
+        CMP     a2,#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     a2,[a1, #40h]               ; Pickup original time slice
+;
+;        /* Clear any active time slice by setting the state to NOT_ACTIVE.  */
+;        TMD_Time_Slice_State =  1;
+;
+        MOV     a3,#1                       ; Build disable value
+        STR     a3,[a4, #0]                 ; Disable time slice
+        STR     a2,[a1, #20h]               ; 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     sp,[a1, #2ch]               ; 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     a2,[a1, #38h]               ; Pickup current thread pointer
+        MOV     a3,#0                       ; Build NU_NULL value
+        STR     a3,[a1, #38h]               ; Clear the protect pointer field
+        STR     a3,[a2, #0]                 ; Release the actual protection
+;
+;    /* Switch to the system stack.  */
+;    REG_Stack_Ptr =  TCD_System_Stack;
+;
+        LDR     a2,System_Stack		    ; Pickup address of stack pointer
+        LDR     a3,System_Limit		    ; Pickup address of stack limit ptr
+        LDR     sp,[a2, #0]                 ; Switch to system stack
+        LDR     v7,[a3, #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.       */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* CALLED BY                                                             */
+;/*                                                                       */
+;/*      TCC_Signal_Shell                    Signal handling shell func   */
+;/*                                                                       */
+;/* CALLS                                                                 */
+;/*                                                                       */
+;/*      TCT_Schedule                        Scheduler                    */
+;/*                                                                       */
+;/* INPUTS                                                                */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* OUTPUTS                                                               */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* HISTORY                                                               */
+;/*                                                                       */
+;/*         NAME            DATE                    REMARKS               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;VOID  TCT_Signal_Exit(void)
+;{
+	.def	$TCT_Signal_Exit
+$TCT_Signal_Exit			    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Signal_Exit
+;
+        .def    _TCT_Signal_Exit
+_TCT_Signal_Exit
+;
+;    /* Lockout interrupts.  */
+;
+        MRS     a4,CPSR                     ; Pickup current CPSR
+        ORR     a4,a4,#LOCKOUT              ; Build lockout value
+        MSR     CPSR,a4                     ; Lockout interrupts
+;
+;    /* Setup a pointer to the thread control block.  */
+;    REG_Thread_Ptr =  (TC_TCB *) TCD_Current_Thread;
+;
+        LDR     a2,Current_Thread	    ; Pickup address of thread pointer
+        MOV     a3,#0                       ; Build NU_NULL value
+        LDR     a1,[a2,#0]                  ; Pickup current thread pointer
+;
+;    /* Clear the current thread control block.  */
+;    TCD_Current_Thread =  NU_NULL;
+;
+        LDR     a4,Slice_State		    ; Pickup time slice state address
+        STR     a3,[a2, #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     a2,[a4, #0]                 ; Pickup time slice state flag
+        CMP     a2,#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     a2,[a1, #40h]               ; Pickup original time slice
+;
+;        /* Clear any active time slice by setting the state to NOT_ACTIVE.  */
+;        TMD_Time_Slice_State =  1;
+;
+        MOV     a3,#1                       ; Build disable value
+        STR     a3,[a4, #0]                 ; Disable time slice
+        STR     a2,[a1, #20h]               ; 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     a2,[a1, #3ch]               ; Pickup saved stack pointer
+        STR     a2,[a1, #2ch]               ; 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     a2,[a1, #38h]               ; Pickup current thread pointer
+        MOV     a3,#0                       ; Build NU_NULL value
+        STR     a3,[a1, #38h]               ; Clear the protect pointer field
+        STR     a3,[a2, #0]                 ; Release the actual protection
+;
+;    /* Switch to the system stack.  */
+;    REG_Stack_Ptr =  (BYTE_PTR) TCD_System_Stack;
+;
+        LDR     a2,System_Stack		    ; Pickup address of stack pointer
+        LDR     a3,System_Limit	  	    ; Pickup address of stack limit ptr
+        LDR     sp,[a2, #0]                 ; Switch to system stack
+        LDR     v7,[a3, #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.                */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* CALLED BY                                                             */
+;/*                                                                       */
+;/*      Application                                                      */
+;/*      System Components                                                */
+;/*                                                                       */
+;/* CALLS                                                                 */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* INPUTS                                                                */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* OUTPUTS                                                               */
+;/*                                                                       */
+;/*      Pointer to current thread                                        */
+;/*                                                                       */
+;/* HISTORY                                                               */
+;/*                                                                       */
+;/*         NAME            DATE                    REMARKS               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;VOID  *TCT_Current_Thread(void)
+;{
+	.def	$TCT_Current_Thread
+$TCT_Current_Thread			    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Current_Thread
+;
+        .def    _TCT_Current_Thread
+_TCT_Current_Thread
+;
+;    /* Return the current thread pointer.  */
+;    return(TCD_Current_Thread);
+;
+        LDR     a1,Current_Thread	    ; Pickup address of thread pointer
+        LDR     a1,[a1, #0]                 ; Pickup current thread pointer
+        BX      lr                          ; Return to caller
+;}
+;
+;
+;
+;/*************************************************************************/
+;/*                                                                       */
+;/* FUNCTION                                                              */
+;/*                                                                       */
+;/*      TCT_Set_Execute_Task                                             */
+;/*                                                                       */
+;/* DESCRIPTION                                                           */
+;/*                                                                       */
+;/*      This function sets the current task to execute variable under    */
+;/*      protection against interrupts.                                   */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* CALLED BY                                                             */
+;/*                                                                       */
+;/*      TCC Scheduling Routines                                          */
+;/*                                                                       */
+;/* CALLS                                                                 */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* INPUTS                                                                */
+;/*                                                                       */
+;/*      task                                Pointer to task control block*/
+;/*                                                                       */
+;/* OUTPUTS                                                               */
+;/*                                                                       */
+;/*      TCD_Execute_Task                    Modified variable            */
+;/*                                                                       */
+;/* HISTORY                                                               */
+;/*                                                                       */
+;/*         NAME            DATE                    REMARKS               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;VOID  TCT_Set_Execute_Task(TC_TCB *task)
+;{
+	.def	$TCT_Set_Execute_Task
+$TCT_Set_Execute_Task			    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Set_Execute_Task
+;
+        .def    _TCT_Set_Execute_Task
+_TCT_Set_Execute_Task
+;
+;    /* Now setup the TCD_Execute_Task pointer.  */
+;    TCD_Execute_Task =  task;
+;
+        LDR     a2,Execute_Task	 	    ; Pickup execute task ptr address
+        STR     a1,[a2,#0]                  ; Setup new task to execute
+        BX      lr                          ; Return to caller
+;}
+;
+;
+;
+;/*************************************************************************/
+;/*                                                                       */
+;/* FUNCTION                                                              */
+;/*                                                                       */
+;/*      TCT_Protect                                                      */
+;/*                                                                       */
+;/* DESCRIPTION                                                           */
+;/*                                                                       */
+;/*      This function protects against multiple thread access.           */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* CALLED BY                                                             */
+;/*                                                                       */
+;/*      Application                                                      */
+;/*      System Components                                                */
+;/*                                                                       */
+;/* CALLS                                                                 */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* INPUTS                                                                */
+;/*                                                                       */
+;/*      protect                            Pointer to protection block   */
+;/*                                                                       */
+;/* OUTPUTS                                                               */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* HISTORY                                                               */
+;/*                                                                       */
+;/*         NAME            DATE                    REMARKS               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;VOID  TCT_Protect(TC_PROTECT *protect)
+;{
+	.def	$TCT_Protect
+$TCT_Protect				    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Protect
+;
+        .def    _TCT_Protect
+_TCT_Protect
+;
+;    /* Determine if the caller is in a task or HISR thread.  */
+;    if (TCD_Current_Thread)
+;    {
+;
+        LDR     a2,Current_Thread	    ; Pickup current thread ptr address
+        LDR     a4,[a2, #0]                 ; Pickup current thread pointer
+        CMP     a4,#0                       ; Check to see if it is non-NULL
+        BEQ     TCT_Skip_Protect            ; If NULL, skip protection
+;    
+;        /* Lockout interrupts.  */
+;
+        MRS     a2,CPSR                     ; Pickup current CPSR
+        ORR     a2,a2,#LOCKOUT              ; Place lockout value in
+        MSR     CPSR,a2                     ; Lockout interrupts
+;    
+;        /* Wait until the protect structure is available.  */
+;        while (protect -> tc_tcb_pointer != NU_NULL)
+;        {
+;
+TCT_Protect_Loop
+        LDR     a2,[a1, #0]                 ; Pickup protection owner field
+        CMP     a2,#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     a3,#1                       ; Build thread waiting flag
+        STR     a3,[a1, #4]                 ; Set waiting field
+;
+;            /* Directly schedule the thread waiting.  */
+;            TCT_Schedule_Protected(protect -> tc_tcb_pointer);
+;            
+        STR     a1,[sp, #-4]!               ; Save a1 on the stack
+        STR     lr,[sp, #-4]!               ; Save lr on the stack
+        MOV     a1,a4                       ; Place current thread into a1
+        BL      _TCT_Schedule_Protected     ; Call routine to schedule the 
+                                            ;   owner of the thread
+;
+        LDR     lr,[sp], #4                 ; Recover saved lr
+        LDR     a1,[sp], #4                 ; Recover saved a1
+;
+;            /* Lockout interrupts.  */
+;
+        LDR     a2,Current_Thread	    ; Pickup current thread ptr address
+        LDR     a4,[a2, #0]                 ; Pickup current thread pointer
+        MRS     a2,CPSR                     ; Pickup current CPSR
+        ORR     a2,a2,#LOCKOUT              ; Place lockout value in
+        MSR     CPSR,a2                     ; 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     a4,[a1, #0]                 ; Indicate calling thread owns this
+                                            ;   protection
+;        
+;        /* Clear the thread waiting flag.  */
+;        protect -> tc_thread_waiting =  0;
+;        
+        MOV     a3,#0                       ; Clear value
+        STR     a3,[a1, #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     a1,[a4, #38h]               ; Setup current protection
+;
+;        /* Restore interrupts.  */
+;
+        LDR     a3,Int_Level	 	    ; Pickup address of interrupt level
+        MRS     a2,CPSR                     ; Pickup current CPSR
+        LDR     a4,[a3, #0]                 ; Pickup interrupt lockout level
+        BIC     a2,a2,#LOCK_MSK             ; Clear lockout bits
+        ORR     a2,a2,a4                    ; Build new interrupt lockout
+        MSR     CPSR,a2                     ; Setup CPSR appropriately
+;    }
+;
+TCT_Skip_Protect
+        BX      lr                          ; 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.                                              */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* CALLED BY                                                             */
+;/*                                                                       */
+;/*      Application                                                      */
+;/*      System Components                                                */
+;/*                                                                       */
+;/* CALLS                                                                 */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* INPUTS                                                                */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* OUTPUTS                                                               */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* HISTORY                                                               */
+;/*                                                                       */
+;/*         NAME            DATE                    REMARKS               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;VOID  TCT_Unprotect(void)
+;{
+	.def	$TCT_Unprotect
+$TCT_Unprotect				    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Unprotect
+;
+        .def    _TCT_Unprotect
+_TCT_Unprotect
+;
+;
+;    /* Determine if the caller is in a task or HISR thread.  */
+;    if (TCD_Current_Thread)
+;    {
+;
+        LDR     a2,Current_Thread	    ; Pickup current thread ptr address
+        LDR     a4,[a2, #0]                 ; Pickup current thread pointer
+        CMP     a4,#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     a1,[a4, #38h]               ; Pickup current protect field
+        CMP     a1,#0                       ; Is there a protection in force?
+        BEQ     TCT_Skip_Unprotect          ; If not, nothing is protected
+;        
+;             /* Lockout interrupts.  */
+;    
+        MRS     a2,CPSR                     ; Pickup current CPSR
+        ORR     a2,a2,#LOCKOUT              ; Place lockout value in
+        MSR     CPSR,a2                     ; 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     a3,[a1, #4]                 ; Pickup thread waiting flag
+        CMP     a3,#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     a3,#0                       ; Build NU_NULL value
+        STR     a3,[a1, #0]                 ; Release the protection
+        STR     a3,[a4, #38h]               ; Clear protection pointer in the
+                                            ;   control block
+;                
+;            }
+;
+TCT_Not_Protected
+;            /* Restore interrupts again.  */
+;
+        LDR     a3,Int_Level		    ; Pickup address of interrupt level
+        MRS     a2,CPSR                     ; Pickup current CPSR
+        LDR     a4,[a3, #0]                 ; Pickup interrupt lockout level
+        BIC     a2,a2,#LOCK_MSK             ; Clear lockout bits
+        ORR     a2,a2,a4                    ; Build new interrupt lockout
+        MSR     CPSR,a2                     ; Setup CPSR appropriately
+;
+;        }
+;    }
+TCT_Skip_Unprotect
+        BX      lr                          ; Return to caller
+;}
+;
+;
+;
+;/*************************************************************************/
+;/*                                                                       */
+;/* FUNCTION                                                              */
+;/*                                                                       */
+;/*      TCT_Unprotect_Specific                                           */
+;/*                                                                       */
+;/* DESCRIPTION                                                           */
+;/*                                                                       */
+;/*      This function releases a specific protection structure.          */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* CALLED BY                                                             */
+;/*                                                                       */
+;/*      Application                                                      */
+;/*      System Components                                                */
+;/*                                                                       */
+;/* CALLS                                                                 */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* INPUTS                                                                */
+;/*                                                                       */
+;/*      protect                            Pointer to protection block   */
+;/*                                                                       */
+;/* OUTPUTS                                                               */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* HISTORY                                                               */
+;/*                                                                       */
+;/*         NAME            DATE                    REMARKS               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;VOID   TCT_Unprotect_Specific(TC_PROTECT *protect)
+;{
+	.def	$TCT_Unprotect_Specific
+$TCT_Unprotect_Specific			    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Unprotect_Specific
+;
+        .def    _TCT_Unprotect_Specific
+_TCT_Unprotect_Specific
+;
+;    /* Determine if the caller is in a task or HISR thread.  */
+;    if (TCD_Current_Thread)
+;    {
+;
+        LDR     a2,Current_Thread	    ; Pickup current thread ptr address
+        LDR     a4,[a2, #0]                 ; Pickup current thread pointer
+        CMP     a4,#0                       ; Check to see if it is non-NULL
+        BEQ     TCT_Skip_Unprot_Spec        ; If NULL, skip unprotect specific
+;     
+;        /* Lockout interrupts.  */
+;
+        MRS     a2,CPSR                     ; Pickup current CPSR
+        ORR     a2,a2,#LOCKOUT              ; Place lockout value in
+        MSR     CPSR,a2                     ; Lockout interrupts
+;
+;        /* Clear the protection pointer.  */
+;        protect -> tc_tcb_pointer =  NU_NULL;
+;        
+        MOV     a3,#0                       ; Build NU_NULL value
+        STR     a3,[a1, #0]                 ; Clear protection ownership
+;
+;        /* Determine if a thread is waiting.  */
+;        if (protect -> tc_thread_waiting)
+;        {
+;
+        LDR     a2,[a1, #4]                 ; Pickup the waiting field
+        CMP     a2,#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   sp!,{v1-ip,lr}              ; Save minimal context of thread on
+                                            ;   the current stack
+	MOV	a3,lr			    ; Determine what state the
+	MOV	a3,a3,LSL #31   	    ;   caller was in and build an
+	MOV	a3,a3,LSR #26		    ;   appropriate state mask
+	STR	a3,[sp, #-4]!		    ; Place it on the stack
+        MOV     a3,#0                       ; Build solicited stack type value
+                                            ;   and NU_NULL value
+        STR     a3,[sp, #-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     a2,Current_Thread	    ; Pickup current thread ptr address
+        LDR     a1,[a2, #0]                 ; Pickup current thread pointer
+;
+;            /* Clear the current thread control block pointer.  */
+;            TCD_Current_Thread =  NU_NULL;
+;    
+        LDR     a4,Slice_State		    ; Pickup time slice state address
+        STR     a3,[a2, #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     a2,[a4, #0]                 ; Pickup time slice state flag
+        CMP     a2,#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     a2,[a1, #40h]               ; Pickup original time slice
+;
+;                /* Clear any active time slice by setting the state to 
+;                   NOT_ACTIVE.  */
+;                TMD_Time_Slice_State =  1;
+;
+        MOV     a3,#1                       ; Build disable value
+        STR     a3,[a4, #0]                 ; Disable time slice
+        STR     a2,[a1, #20h]               ; 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     sp,[a1, #2ch]               ; Save the thread's stack pointer
+;
+;            /* Switch to the system stack.  */
+;            REG_Stack_Ptr =  TCD_System_Stack;
+;
+        LDR     a2,System_Stack		    ; Pickup address of stack pointer
+        LDR     a3,System_Limit		    ; Pickup address of stack limit ptr
+        LDR     sp,[a2, #0]                 ; Switch to system stack
+        LDR     v7,[a3, #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     a3,Int_Level		    ; Pickup address of interrupt level
+        MRS     a2,CPSR                     ; Pickup current CPSR
+        LDR     a4,[a3, #0]                 ; Pickup interrupt lockout level
+        BIC     a2,a2,#LOCK_MSK             ; Clear lockout bits
+        ORR     a2,a2,a4                    ; Build new interrupt lockout
+        MSR     CPSR,a2                     ; Setup CPSR appropriately
+;
+;        }
+;    }
+;
+TCT_Skip_Unprot_Spec
+        BX      lr                          ; 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.      */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* CALLED BY                                                             */
+;/*                                                                       */
+;/*      TCC_Resume_Task                    Resume task function          */
+;/*                                                                       */
+;/* CALLS                                                                 */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* INPUTS                                                                */
+;/*                                                                       */
+;/*      protect                            Pointer to protection block   */
+;/*                                                                       */
+;/* OUTPUTS                                                               */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* HISTORY                                                               */
+;/*                                                                       */
+;/*         NAME            DATE                    REMARKS               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;VOID  TCT_Set_Current_Protect(TC_PROTECT *protect)
+;{
+	.def	$TCT_Set_Current_Protect
+$TCT_Set_Current_Protect		    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Set_Current_Protect
+;
+        .def    _TCT_Set_Current_Protect
+_TCT_Set_Current_Protect
+;
+;    /* Determine if the caller is in a task or HISR thread.  */
+;    if (TCD_Current_Thread)
+;    {
+;
+        LDR     a2,Current_Thread	    ; Pickup current thread ptr address
+        LDR     a4,[a2, #0]                 ; Pickup current thread pointer
+        CMP     a4,#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   a1,[a4, #38h]               ; Setup new protection
+;    }
+;
+        BX      lr                          ; 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.                                             */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* CALLED BY                                                             */
+;/*                                                                       */
+;/*      System Components                                                */
+;/*                                                                       */
+;/* CALLS                                                                 */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* INPUTS                                                                */
+;/*                                                                       */
+;/*      thread                             Pointer to thread control blk */
+;/*                                                                       */
+;/* OUTPUTS                                                               */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* HISTORY                                                               */
+;/*                                                                       */
+;/*         NAME            DATE                    REMARKS               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;VOID  TCT_Protect_Switch(VOID *thread)
+;{
+	.def	$TCT_Protect_Switch
+$TCT_Protect_Switch			    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Protect_Switch
+;
+        .def    _TCT_Protect_Switch
+_TCT_Protect_Switch
+;
+;    /* Lockout interrupts.  */
+;    
+        MRS     a2,CPSR                     ; Pickup current CPSR
+        ORR     a2,a2,#LOCKOUT              ; Place lockout value in
+        MSR     CPSR,a2                     ; 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     a2,[a1, #38h]               ; Pickup protection of specified
+                                            ;   thread
+        CMP     a2,#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     a3,#1                       ; Build waiting flag value
+        STR     a3,[a2, #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     a3,Current_Thread	    ; Pickup current thread ptr address
+        STR     a1,[sp, #-4]!               ; Save a1 on the stack
+        STR     lr,[sp, #-4]!               ; Save lr on the stack
+        MOV     a2,a1                       ; Move new thread into a2
+        LDR     a1,[a3, #0]                 ; Pickup current thread pointer
+        BL      _TCT_Schedule_Protected     ; Call routine to schedule the 
+                                            ;   owner of the thread
+;
+        LDR     lr,[sp], #4                 ; Recover saved lr
+        LDR     a1,[sp], #4                 ; Recover saved a1
+;            
+;        /* Lockout interrupts.  */
+;
+        B       _TCT_Protect_Switch         ; Branch to top of routine and 
+                                            ;   start over
+;    }
+TCT_Switch_Done
+;
+;    /* Restore interrupts.  */
+;
+        LDR     a3,Int_Level	            ; Pickup address of interrupt level
+        MRS     a2,CPSR                     ; Pickup current CPSR
+        LDR     a4,[a3, #0]                 ; Pickup interrupt lockout level
+        BIC     a2,a2,#LOCK_MSK             ; Clear lockout bits
+        ORR     a2,a2,a4                    ; Build new interrupt lockout
+        MSR     CPSR,a2                     ; Setup CPSR appropriately
+;
+        BX      lr                          ; 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.                             */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* 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               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;VOID  TCT_Schedule_Protected(VOID *thread)
+;{
+;
+_TCT_Schedule_Protected
+;
+;    /* Interrupts are already locked out by the caller.  */
+;    
+;    /* Save minimal context required by the system.  */
+;
+        STMDB   sp!,{v1-ip,lr}              ; Save minimal context of thread on
+                                            ;   the current stack
+	MOV	a3,lr			    ; Determine what state the
+	MOV	a3,a3,LSL #31   	    ;   caller was in and build an
+	MOV	a3,a3,LSR #26		    ;   appropriate state mask
+	STR	a3,[sp, #-4]!		    ; Place it on the stack
+        MOV     a3,#0                       ; Build solicited stack type value
+                                            ;   and NU_NULL value
+        STR     a3,[sp, #-4]!               ; Place it on the top of the stack
+        MOV     v1,a2                       ; Save thread to schedule
+;
+;    /* Setup a pointer to the thread control block.  */
+;    REG_Thread_Ptr =  (TC_TCB *) TCD_Current_Thread;
+;    
+        LDR     a2,Current_Thread	    ; Pickup current thread ptr address
+;
+;    /* Clear the current thread control block.  */
+;    TCD_Current_Thread =  NU_NULL;
+;
+        LDR     a4,Slice_State		    ; Pickup time slice state address
+        STR     a3,[a2, #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     a2,[a4, #0]                 ; Pickup time slice state flag
+        CMP     a2,#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     a2,[a1, #40h]               ; Pickup original time slice
+;
+;        /* Clear any active time slice by setting the state to NOT_ACTIVE.  */
+;        TMD_Time_Slice_State =  1;
+;
+        MOV     a3,#1                       ; Build disable value
+        STR     a3,[a4, #0]                 ; Disable time slice
+        STR     a2,[a1, #20h]               ; 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     sp,[a1, #2ch]               ; Save the thread's stack pointer
+;
+;    /* Switch to the system stack.  */
+;    TCD_System_Stack =  (VOID *) REG_Stack_Ptr;
+;
+        LDR     a2,System_Stack		    ; Pickup address of stack pointer
+        LDR     a3,System_Limit		    ; Pickup address of stack limit ptr
+        LDR     sp,[a2, #0]                 ; Switch to system stack
+        LDR     v7,[a3, #0]                 ; Setup system stack limit
+;
+;    /* Transfer control to the specified thread directly. */
+;    TCT_Control_To_Thread(thread);
+;
+        LDR     a3,Int_Level		    ; Pickup address of interrupt level
+        MRS     a2,CPSR                     ; Pickup current CPSR
+        LDR     a4,[a3, #0]                 ; Pickup interrupt lockout level
+        BIC     a2,a2,#LOCK_MSK             ; Clear lockout bits
+        ORR     a2,a2,a4                    ; Build new interrupt lockout
+        MOV     a1,v1                       ; Indicate thread to schedule
+        MSR     CPSR,a2                     ; Setup CPSR appropriately
+        ORR     a2,a2,#LOCKOUT              ; Build lockout value again
+        MSR     CPSR,a2                     ; 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.                                      */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* 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               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;VOID  TCT_Interrupt_Context_Save(INT vector)
+;{
+	.def	$TCT_Interrupt_Context_Save
+$TCT_Interrupt_Context_Save		    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Interrupt_Context_Save
+;
+        .def    _TCT_Interrupt_Context_Save
+_TCT_Interrupt_Context_Save
+;
+;    /* This routine is designed to handle THUMB IRQ interrupts.  The IRQ
+;       stack is used as a temporary area.  Actual context is saved either
+;       on the interrupted thread's stack or the system stack- both of which
+;       are in the Supervisor (SVC) mode.  Note:  upon entry to this routine 
+;       a1-a4 are saved on the current stack and a4 contains the original
+;       (interrupt return address) lr value.  The current lr contains the 
+;       ISR return address.  */
+;
+;    /* Determine if this is a nested interrupt.  */
+;    if (TCD_Interrupt_Count++)
+;    {
+;
+        LDR     a1,Int_Count		    ; Pickup address of interrupt count
+        LDR     a2,[a1, #0]                 ; Pickup interrupt counter
+        CMP     a2,#0                       ; Is it the first interrupt?
+        BEQ     TCT_Not_Nested_Save         ; If so, not a nested interrupt
+;    
+;        /* Nested interrupt.  Save complete context on the current stack.  */
+;        
+        ADD     a2,a2,#1                    ; Increment the interrupt counter
+        STR     a2,[a1, #0]                 ; Store in interrupt counter
+        STMDB   sp!,{v1-v3}                 ; Save more registers on current
+                                            ;   stack
+        MRS     v1,SPSR                     ; Pickup and save current SPSR
+        MOV     v2,lr                       ; Save current lr 
+        MOV     v3,sp                       ; Save current sp
+        ADD     sp,sp,#28                   ; Adjust sp for future interrupts
+        MRS     a1,CPSR                     ; Pickup current CPSR
+        BIC     a1,a1,#MODE_MASK            ; Clear the mode bits
+        ORR     a1,a1,#SUP_MODE             ; Prepare to switch to supervisor
+                                            ;   mode (SVC)
+        MSR     CPSR,a1                     ; Switch to SVC mode
+        MOV     a2,sp                       ; Use a non sp register
+        NOP                                 ; 
+        STR     a4,[a2, #-4]!               ; Save interrupted pc on sys stack
+        STMDB   a2!,{v4-lr}   		    ; Save v4-lr on the system stack
+        MOV     sp,a2                       ; Setup sp again
+        LDMIA   v3!,{v4-v6}                 ; Recover v1-v3 from int stack
+        STMDB   sp!,{v4-v6}                 ; Save v1-v3 on the system stack
+        LDMIA   v3,{a1-a4}                  ; Recover a1-a4
+        STMDB   sp!,{a1-a4}                 ; Save a1-a4 on the system stack
+        STR     v1,[sp, #-4]!               ; Save CPSR on the stack
+        BX      v2                          ; Return to calling ISR        
+;    }
+;    else
+;    {
+TCT_Not_Nested_Save
+;    
+        ADD     a2,a2,#1                    ; Increment the interrupt counter
+        STR     a2,[a1, #0]                 ; Store in interrupt counter
+;
+;        /* Determine if a thread was interrupted.  */
+;        if (TCD_Current_Thread)
+;        {
+;
+        LDR     a2,Current_Thread	    ; Pickup current thread ptr address
+        LDR     a2,[a2, #0]                 ; Pickup the current thread pointer
+        CMP     a2,#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.  */
+;
+        STMDB   sp!,{v1-v3}                 ; Save more registers on temp stack
+        MOV     v2,lr                       ; Save interrupt lr in v2
+        MRS     v1,SPSR                     ; Save interrupt SPSR in v1
+        MOV     v3,sp                       ; Save current sp in v3
+        ADD     sp,sp,#28                   ; Adjust sp for future interrupts
+        MRS     a1,CPSR                     ; Pickup current CPSR
+        BIC     a1,a1,#MODE_MASK            ; Clear the mode bits
+        ORR     a1,a1,#SUP_MODE             ; Prepare to switch to supervisor
+                                            ;   mode (SVC)
+        MSR     CPSR,a1                     ; Switch to supervisor mode (SVC)
+        MOV     a2,sp                       ; Use a non-stack pointer register
+        NOP                                 ; 
+        STR     a4,[a2, #-4]!               ; Save interrupted pc on the stack
+        STMDB   a2!,{v4-lr} 	            ; Save v4-lr on the stack
+        MOV     sp,a2                       ; Setup sp again
+        LDMIA   v3!,{v4-v6}                 ; Recover v1-v3 into v4-v6
+        STMDB   sp!,{v4-v6}                 ; Save v1-v3 on the stack
+        LDMIA   v3,{a1-a4}                  ; Recover a1-a4
+        STMDB   sp!,{a1-a4}                 ; Save a1-a4 on the stack
+        STR     v1,[sp, #-4]!               ; Save CPSR on the stack
+        MOV     a2,#1                       ; Interrupt stack type
+        STR     a2,[sp, #-4]!               ; Put interrupt stack type on top 
+                                            ;   of stack
+;
+;            /* 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     a2,Current_Thread	    ; Pickup current thread ptr address
+        LDR     a1,[a2, #0]                 ; Pickup current thread pointer
+        LDR     a4,Slice_State		    ; Pickup time slice state address
+        STR     sp,[a1, #2ch]               ; Save stack pointer
+;
+;            /* Switch to the system stack.  */
+;            REG_Stack_Ptr =  TCD_System_Stack;
+;
+        LDR     a2,System_Stack	  	    ; Pickup address of stack pointer
+        LDR     a3,System_Limit		    ; Pickup address of stack limit ptr
+        LDR     sp,[a2, #0]                 ; Switch to system stack
+        LDR     v7,[a3, #0]                 ; Setup system stack limit
+;
+;            /* Return to caller ISR.  */
+;
+        BX      v2                          ; Return to caller ISR
+;
+;        }
+;
+TCT_Idle_Context_Save
+;
+        MOV     v2,lr                       ; Save lr in v2
+        ADD     sp,sp,#16                   ; Adjust sp for future interrupts
+        MRS     a1,CPSR                     ; Pickup current CPSR
+        BIC     a1,a1,#MODE_MASK            ; Clear the current mode
+        ORR     a1,a1,#SUP_MODE             ; Prepare to switch to supervisor
+                                            ;   mode (SVC)
+        MSR     CPSR,a1                     ; Switch to supervisor mode (SVC)
+        BX      v2                          ; 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.                    */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* 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               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;VOID  TCT_Interrupt_Context_Restore(void)
+;{
+	.def	$TCT_Interrupt_Context_Restore
+$TCT_Interrupt_Context_Restore		    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Interrupt_Context_Restore
+;
+        .def    _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.  */
+;
+;    /* Lockout interrupts.  */
+;    
+        MRS     a2,CPSR                     ; Pickup current CPSR
+        ORR     a2,a2,#LOCKOUT              ; Build lockout value
+        MSR     CPSR,a2                     ; Lockout interrupts
+;
+;    /* Decrement and check for nested interrupt conditions.  */
+;    if (--TCD_Interrupt_Count)
+;    {
+;
+        LDR     a1,Int_Count		    ; Pickup address of interrupt count
+        LDR     a2,[a1, #0]                 ; Pickup interrupt counter
+        SUB     a2,a2,#1                    ; Decrement interrupt counter
+        STR     a2,[a1, #0]                 ; Store interrupt counter
+        CMP     a2,#0                       ; Is this a nested interrupt?
+        BEQ     TCT_Not_Nested_Restore      ; If not, skip nested interrupt 
+                                            ;   restoration
+;    
+;        /* Restore previous context.  */
+;
+        LDR     a1,[sp], #4                 ; Pickup the saved CPSR
+	MSR	SPSR,a1			    ; Put in SPSR
+        LDMIA   sp,{a1-pc}^  		    ; Return to the point of interrupt
+;
+;    }
+;    else
+;    {
+;
+TCT_Not_Nested_Restore
+;    
+;        /* Determine if a thread is active.  */
+;        if (TCD_Current_Thread)
+;        {
+;
+        LDR     a2,Current_Thread	    ; Pickup current thread ptr address
+        LDR     a1,[a2, #0]                 ; Pickup current thread pointer
+        CMP     a1,#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;
+;
+        LDR     a4,Slice_State		    ; Pickup time slice state address
+        MOV     a3,#0                       ; Build NU_NULL value
+        STR     a3,[a2, #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     a2,[a4, #0]                 ; Pickup time slice state
+        CMP     a2,#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     a3,Time_Slice		    ; Pickup address of time slice left
+        MOV     a2,#1                       ; Build disable time slice value
+        LDR     a3,[a3, #0]                 ; Pickup remaining time slice
+        STR     a2,[a4, #0]                 ; Disable time slice
+        STR     a3,[a1, #20h]               ; Store remaining time slice       
+;
+;            }
+;        }
+TCT_Idle_Context_Restore
+;
+;        /* Reset the system stack pointer.  */
+;
+        LDR     a2,System_Stack		    ; Pickup address of stack pointer
+        LDR     a3,System_Limit		    ; Pickup address of stack limit ptr
+        LDR     sp,[a2, #0]                 ; Switch to system stack
+        LDR     v7,[a3, #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.                 */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* CALLED BY                                                             */
+;/*                                                                       */
+;/*      Application LISRs                                                */
+;/*                                                                       */
+;/* CALLS                                                                 */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* INPUTS                                                                */
+;/*                                                                       */
+;/*      hisr                                Pointer to HISR to activate  */
+;/*                                                                       */
+;/* OUTPUTS                                                               */
+;/*                                                                       */
+;/*      NU_SUCCESS                          Successful completion        */
+;/*                                                                       */
+;/* HISTORY                                                               */
+;/*                                                                       */
+;/*         NAME            DATE                    REMARKS               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;STATUS  TCT_Activate_HISR(TC_HCB *hisr)
+;{
+	.def	$TCT_Activate_HISR
+$TCT_Activate_HISR			    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_Activate_HISR
+;
+        .def    _TCT_Activate_HISR
+_TCT_Activate_HISR
+;
+;INT     priority;
+;
+;
+;    /* Lockout interrupts.  */
+;
+        STR     v1,[sp, #-4]!               ; Save v1
+        MRS     v1,CPSR                     ; Pickup current CPSR
+        ORR     a2,v1,#LOCKOUT              ; Build interrupt lockout value
+        MSR     CPSR,a2                     ; Lockout interrupts
+;
+;    /* Determine if the HISR is already active.  */
+;    if (hisr -> tc_activation_count)
+;    {
+;
+        LDR     a2,[a1,#40h]                ; Pickup current activation count
+        CMP     a2,#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    a2,a2,#1                    ; Increment the activation count
+        STR     a2,[a1,#40h]                ; Store new activation count
+;
+;        if (hisr -> tc_activation_count == 0)
+;        
+;            hisr -> tc_activation_count =  0xFFFFFFFFUL;
+;
+        MVNEQ   a2,#0                       ; If counter rolled-over reset
+        STREQ   a2,[a1,#40h]                ; 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     a2,#1                       ; Initial activation count
+        STR     a2,[a1,#40h]                ; 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    a2,[a1,#1ah]                ; Pickup priority of HISR
+        LDR     a3,HISR_Tails	            ; Pickup tail pointer base
+        LDR     a4,[a3,a2,LSL #2]           ; Pickup tail pointer for priority
+        CMP     a4,#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     a1,[a4,#3ch]                ; Setup the active next pointer
+        STR     a1,[a3,a2,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     a4,HISR_Heads		    ; Pickup address of head pointers
+        STR     a1,[a3,a2,LSL #2]           ; Set tail pointer to this HISR
+        STR     a1,[a4,a2,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     a2,[a4,#0]                  ; Pickup priority 0 head pointer
+        LDR     a1,Execute_HISR		    ; Build address to execute HISR ptr
+        CMP     a2,#0                       ; Is priority 0 active?
+        LDREQ   a2,[a4,#4]                  ; If not, pickup priority 1 head 
+        CMPEQ   a2,#0                       ; Is priority 1 active?
+        LDREQ   a2,[a4,#8]                  ; Else, must be priority 2 active
+        STR     a2,[a1,#0]                  ; Store which ever priority is the
+                                            ;   active one
+;       }
+;    }
+TCT_Activate_Done
+;
+        MSR     CPSR,v1                     ; Restore interrupt lockout
+        LDR     v1,[sp], #4                 ; Restore corrupted v1
+;
+;    return(NU_SUCCESS);
+;
+        MOV     a1,#0                       ; Always return NU_SUCCESS
+        BX      lr                          ; 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.                 */
+;/*                                                                       */
+;/* AUTHOR                                                                */
+;/*                                                                       */
+;/*      Barry Sellew, Accelerated Technology, Inc.                       */
+;/*                                                                       */
+;/* CALLED BY                                                             */
+;/*                                                                       */
+;/*      HISR Scheduling                                                  */
+;/*                                                                       */
+;/* CALLS                                                                 */
+;/*                                                                       */
+;/*      hisr -> tc_entry                    Actual entry function of HISR*/
+;/*                                                                       */
+;/* INPUTS                                                                */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* OUTPUTS                                                               */
+;/*                                                                       */
+;/*      None                                                             */
+;/*                                                                       */
+;/* HISTORY                                                               */
+;/*                                                                       */
+;/*         NAME            DATE                    REMARKS               */
+;/*                                                                       */
+;/*      B. Sellew       01-19-1996      Created initial version 1.0      */
+;/*	 B. Sellew	 01-22-1996	 Verified version 1.0		  */
+;/*                                                                       */
+;/*************************************************************************/
+;VOID    TCT_HISR_Shell(void)
+;{
+	.def	$TCT_HISR_Shell
+$TCT_HISR_Shell				    ; Dual-state interworking veneer
+	.state16
+	BX	pc
+	NOP
+	.state32
+	B	_TCT_HISR_Shell
+;
+        .def    _TCT_HISR_Shell
+_TCT_HISR_Shell
+;
+;    /* Point at the HISR.  */
+;    REG_HISR_Ptr =  (TC_HCB *) TCD_Current_Thread;
+;
+        LDR     a1,Current_Thread	    ; Build address of thread pointer
+        LDR     v2,[a1, #0]                 ; Pickup control block pointer
+;
+;    do
+;    {
+TCT_HISR_Loop
+;
+;        /* Call the HISR's entry routine.  */
+;        (*(REG_HISR_Ptr -> tc_entry)) ();
+;
+        LDR     v1,[v2,#44h]                ; Call HISR entry function
+	BL	IND_CALL		    ;    indirectly
+;
+;        /* Lockout interrupts.  */
+;
+        MRS     a2,CPSR                     ; Pickup current CPSR
+        ORR     a2,a2,#LOCKOUT              ; Build interrupt lockout 
+        MSR     CPSR,a2                     ; 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     a1,[v2, #40h]               ; Pickup current activation count
+        SUBS    a1,a1,#1                    ; Subtract and set condition codes
+        STR     a1,[v2, #40h]               ; Store new activation count
+        BEQ     TCT_HISR_Finished           ; Finished processing HISR
+
+;        /* Restore interrupts.  */
+;
+        LDR     a3,Int_Level		    ; Pickup address of interrupt level
+        MRS     a2,CPSR                     ; Pickup current CPSR
+        LDR     a4,[a3, #0]                 ; Pickup interrupt lockout level
+        BIC     a2,a2,#LOCK_MSK             ; Clear lockout bits
+        ORR     a2,a2,a4                    ; Build new interrupt lockout
+        MSR     CPSR,a2                     ; 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     lr,HISR_Tails		    ; Pickup tail pointers address
+        LDRB    a4,[v2,#1ah]                ; Pickup priority
+        LDR     v3,[lr,a4,LSL #2]           ; Pickup this priority tail pointer
+        LDR     a3,Execute_HISR		    ; Build address to execute HISR ptr
+        MOV     a1,#0                       ; Clear a1
+        LDR     a2,HISR_Heads		    ; Pickup head pointers address
+        CMP     v3,v2                       ; 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     a1,[a2,a4,LSL #2]           ; Set head pointer to NU_NULL
+        STR     a1,[lr,a4,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     a4,[a2,#0]                  ; Pickup priority 0 head pointer
+        CMP     a4,#0                       ; Is there an HISR active?
+        LDREQ   a4,[a2,#4]                  ; If not, pickup priority 1 pointer
+        CMPEQ   a4,#0                       ; Is there an HISR active?
+        LDREQ   a4,[a2,#8]                  ; If not, pickup priority 2 pointer
+        STR     a4,[a3,#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     lr,[v2,#3ch]                ; Pickup next HISR to activate
+        STR     lr,[a2,a4,LSL #2]           ; Setup new head pointer
+        STR     lr,[a3, #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     lr,HISR_Shell		    ; Pickup address of shell entry
+        STMDB   sp!,{v1-ip,lr}              ; Save minimal context of thread on
+                                            ;   the current stack
+        MOV     a3,#0                       ; Build solicited stack type value
+                                            ;   and NU_NULL value
+	STR	a3,[sp, #-4]!		    ; Save state mask
+        STR     a3,[sp, #-4]!               ; Place it on the top of the stack
+;
+;    /* Clear the current thread control block.  */
+;    TCD_Current_Thread =  NU_NULL;
+;
+        LDR     a2,Current_Thread	    ; Pickup current thread ptr address
+        STR     a3,[a2, #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     sp,[v2, #2ch]               ; Save the thread's stack pointer
+;
+;    /* Switch to the system stack.  */
+;    REG_Stack_Ptr =  (BYTE_PTR) TCD_System_Stack;
+;
+        LDR     a2,System_Stack		    ; Pickup address of stack pointer
+        LDR     a3,System_Limit		    ; Pickup address of stack limit ptr
+        LDR     sp,[a2, #0]                 ; Switch to system stack
+        LDR     v7,[a3, #0]                 ; Setup system stack limit
+;
+;    /* Transfer control to the main scheduling loop.  */
+;
+        B       _TCT_Schedule               ; Return to main scheduling loop
+;}
+;
+;/* Define the global addresses used in this section */
+;
+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
+;
+System_Error
+	.word	$ERC_System_Error
+;
+        .end