view chipsetsw/os/nucleus/tct.s @ 338:a4a1c5bb4be6

macs.c: initial import from LoCosto source
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 29 Oct 2017 18:54:50 +0000
parents 509db1a7b7b8
children
line wrap: on
line source

;/*************************************************************************/
;/*                                                                       */
;/*        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