
/***************************************************************************
**
**    $Header:   D:/EP196/SRC/LOG/SYMSVR/STKSVR.CPP   1.0   15 Aug 1997 14:04:12   ZJRD  $
**
**    $Log:   D:/EP196/SRC/LOG/SYMSVR/STKSVR.CPP  $
** 
**    Rev 1.0   15 Aug 1997 14:04:12   ZJRD
** Initial revision.
** 
****************************************************************************/

/****************************************************************************
**
**  Name:  STKSVR.CPP
**
**  Description:
**      Routines for stack server.
**
**  Status:  CODED
**
**    Rev 1.0   1 Sept. 1995 8:30:00am   Gates Hua
** Initial revision.
**
**    Rev 1.1   8 Sept. 1995 12:00:00am   Gates Hua
**        For bug 0045 , Modify the routine StkGetNodeDisplayString()
**
**    Rev 1.2  12 Oct. 1995 13:00:00pm   Gates Hua
**        For bug 01945 , Modify the routine buildStack()
**
**  Copyright (C) 1995 Microtek International.  All rights reserved.
**
*****************************************************************************/

            /***************************
            *                          *
            *       INCLUDE FILES      *
            *                          *
            ***************************/
#include "stdafx.h"

//#define new DEBUG_NEW 

#ifdef _LINK_WITH_ABI_
//#include "abibase.h"  
#include "abiextfn.h"
#else


/* All ABI routines Return codes */
typedef enum {
        ICE_OK              = 0x0,
        ICE_FAIL_STEP,                  //target cannot step
        ICE_FAIL_MEM_WRITE,             //memory write failure
        ICE_FAIL_MAP_INCLUDE,           //map status not included
        ICE_FAIL_MAP_BOUNDARY,          //map address boundary error
        ICE_NOT_FOUND       = 0x5,
        ICE_FOUND,
        ICE_TIME_OUT        = 0x7,
        ICE_PARA_ERROR      = 0x8,
        ICE_EP_RUNNING      = 0x10,
        ICE_TRACE_RUNNING   = 0x11,
        ICE_TRACE_READ_OVER = 0x12,
        ICE_COMMAND_INVALID = 0x13,

        ICE_FLASH_SW_ERROR  = 0x40,
        ICE_FLASH_EC_ERROR  = 0x41,
        ICE_FLASH_PRG_ERROR = 0x42,
        ICE_FLASH_REC_ERROR = 0x43,
		ICE_NO_RESPONSE		= 0xff
} RET_CODE;

#endif

#include "symblsvr.h"
#include "stkinit.h"
#include "varinit.h"
#include "sympool.h"
#include "symmgr.h"

#include "stksvr.h"   
#include "symimp.h"
#include "ldrexp.h"
#include "cpusvr.h"
//BOOL stkServer::m_isStkDirty = 1;


            /***************************
            *                          *
            *        EXTERNALS         *
            *                          *
            **************************/
extern MemPool st;
typedef unsigned char FAR*   ULPSTR        ; 
//extern BOOL GetCpuStatus(unsigned char & uchStatus);

//extern BOOL IsLibFunction( U32 uAddr );
extern int IsSrcStatement(void);

extern int SrcIsLoaded(void);
extern RETCODE
SymAddGetModuleName(SYM_DESCRIPTOR module, LPSTR modName);
extern void U16ToStr(U16 ui , char *tt);
extern void U24ToStr(U32 ui , char *tt);
int SrcIsStatement(void);
int SrcIsIEEE(void);
int FindNextType(TYPE_INDEX oldType , TYPE_INDEX& nextIndex);
int BuildEnumValue(TYPE_INDEX typeIndex,SEGMENTTYPE type,U32 addr,
    int nFlag , char* str );
extern BOOL cpuStatus(); 
            /***************************
            *                          *
            *        DEFINITIONS       *
            *                          *
            ***************************/

/* maximum number of stacks supported; must fit in a U8 size */
#define MAX_NUMBER_OF_STACKS 50

/* max number of bytes making up a stack work */
#define NULL_CONTEXT 0L

#define STACK_PATTERN_LENGTH 2

            /***************************
            *                          *
            *     LOCAL PROTOTYPES     *
            *                          *
            ***************************/
               
void DisplayStack();
RETCODE PRIVATE StkGetStackInfoFromLoader(VOID);
RETCODE WINAPI StkCallback(U32 eventNum);
RETCODE PRIVATE StkValidateStackArea(U32 stackStart, 
                                     U32 stkMaxAddress,
                                     U32 *stackSizeParam);

int ConvertToFunc(SYM_DESCRIPTOR desc , SYM_DESCRIPTOR& nextDesc);
int DisplayParameters(U32 addr,SYM_DESCRIPTOR desc , char* tmpStr);
int DisplayOneParameter(SYM_DESCRIPTOR desc , char* tmpStr);
int BuildComplexAddr( SEGMENTTYPE type , U32 addr , char* str );
int BuildSimpleValue(TYPE_INDEX typeIndex,SEGMENTTYPE type,U32 addr,char* str );
int BuildBitValue(TYPE_INDEX typeIndex,
        SEGMENTTYPE type,U32 addr,char* str );
void ConvEnumToAbiType( SEGMENTTYPE type , U16& addrType );
void Omf51ConvPtrToSeg( char c , SEGMENTTYPE& type );
void UbrofConvPtrToSeg( char c , SEGMENTTYPE& type );
void MemoryTypeConvToSeg( MEMORY_TYPE t , SEGMENTTYPE& type );

void VarU8ToStr(U8 ui,char *s);
void VarU32ToStr(U32 ul,char *s);
void VarU16ToStr(U16 ui,char *s);
int BuildIEEEBValue(struct VarNode *node, int nFlag, 
    char* str );
RETCODE 
SymGetFuncExt(SYM_DESCRIPTOR inputSymbol,
           LPSTR          funcName,
           FUNC_CLASS     *funcClass,
           U32            *stackSize,
           ADDR_RANGE_TYPE *codeAddrRange,
           U16 *nFramePtr,
           U32 *retOffset,
           BOOL *bFrameFlag,
           U8 * prologBytes ); 
int FuncFirstLine(SYM_DESCRIPTOR moduleDesc,
					SYM_DESCRIPTOR funcDesc, U32 addr);
RETCODE IARGetFuncLocalVarBytes(SYM_DESCRIPTOR funcSymbol,
								U16& overlayBytes,U16& autoBytes); 
RETCODE IARGetFuncParamBytes(SYM_DESCRIPTOR funcSymbol,U16& bytes);
            /**************************
            *                         *
            *    PRIVATE VARIABLES    *
            *                         *
            **************************/

//class stkServer stkObject;
class VarServer stkObject;
extern class VarServer varObject;
U32 stkCurrentPC = 0L;
U32 stkCurrentSP = 07L;

U32 stkMaxAddress;   /* global max address for other modules */

U32 defaultStackSize;

/* symbolic context of present Program Counter */
PRIVATE SYM_DESCRIPTOR stkModuleDesc;
PRIVATE SYM_DESCRIPTOR stkFunctionDesc;
PRIVATE SYM_DESCRIPTOR stkLowestLevelDesc;
PRIVATE U32 stkSymbolOffset;  /* distance from currentPC to found symbol */

/* current line number information; values = 0 if none found */
PRIVATE LINENUM_TYPE stkCurrentLinenum;
PRIVATE COLUMN_TYPE  stkCurrentColumn;
PRIVATE LINENUM_DESCRIPTOR stkLinenumIndex;

PRIVATE const U16 stackSearchPattern = 0x55AA;

PRIVATE const U32 stackFillPattern   = 0x55AA55AAL;
RETCODE GetFuncLocalVarBytes(SYM_DESCRIPTOR funcSymbol,U16& bytes) ;
RETCODE GetFuncParamBytes(SYM_DESCRIPTOR funcSymbol,U16& bytes);

/* the constant "4" below must be modified if roundingMask type size (U32)
   changes */
#define MAX_STACK_BYTES (sizeof(U32) / 4)

            /**************************** 
             *                          *
             *     EXECUTABLE CODE      *
             *                          *
             ****************************/

/*------------------------------------------------------------------------
** StkInitStack
**
** Purpose:
**    Initialize all the PRIVATE variables used in this module; only called
**    once in initialization.
**
** Input parameters: none
**
** Output parameters: none
*/
/*------------------------------------------------------------------------*/
RETCODE StkInitStack()  {

    stkModuleDesc = NULL_SYMBOL;
    stkFunctionDesc = NULL_SYMBOL;
    stkLowestLevelDesc = NULL_SYMBOL;

    stkCurrentLinenum = 0;
    stkCurrentColumn = 0;
    stkLinenumIndex = 0;
    return GOOD;
}  /* end of StkInitStackContext */

/*------------------------------------------------------------------------
** StkCalcSymbolicInfo
**
** Purpose:
**    maps current PC to symbols and saves symbol descriptors for
**    any caller to access.
**    CHANGE: uses private variable holding last-calculated address to
**    compare against.  If current PC is same, function returns.  If
**    different, symbolics are calculated for new address.
*/
/*------------------------------------------------------------------------*/
RETCODE WINAPI StkCalcSymbolicInfo()  {

   ADDRESS_TYPE     addr;   
   U32              currentPC;
   RETCODE          err = GOOD;
   RETCODE          firstErr = GOOD;
   MEM_ADDR_CLASS   memoryClass;
   SYM_TYPE_TYPE    symbolType;
   ADDR_RANGE_TYPE  addrRange;
   U32     regValue;

    currentPC = 0;

#ifdef _LINK_WITH_ABI_

//    if (ICE_OK != (err = AbiGetOneReg(0 , &regValue)))
//        return FAILURE;
    if (ICE_OK != (err = emuGetReg(0,0,&regValue))) {
    	StkInitStack();
        return GOOD;  // go running or communication failure
    }
    
    currentPC = (U32) regValue;     
    stkCurrentPC = (U32) regValue;  /* save returned addr from CPU */

    if (ICE_OK != (err = emuGetReg(0,1,&regValue)))    //Get SP
        return FAILURE;
    
    stkCurrentSP = (U32) regValue;  /* save returned addr from CPU */

#endif

    addr.addr = currentPC;
    addr.segType = (SEGMENTTYPE) SEG_CODE;  
    err = SymMapAddr2Symbol(addr,
               &memoryClass,
               &symbolType,
               &stkSymbolOffset,
               &stkLowestLevelDesc,
               &stkFunctionDesc,
               &stkModuleDesc);
    if (GOOD == err) {
        if ((stkLowestLevelDesc != NULL_SYMBOL) ||
            (stkModuleDesc      != NULL_SYMBOL)) {
               firstErr = SymMapAddr2Linenum(currentPC,
                         stkModuleDesc,
                         &stkCurrentLinenum,
                         &stkCurrentColumn,
                         &addrRange,
                         &stkLinenumIndex);
        }
    }

   if (GOOD != err) {  /* clear out vars if error occurred */
      stkModuleDesc = NULL_SYMBOL;
      stkFunctionDesc = NULL_SYMBOL;
      stkLowestLevelDesc = NULL_SYMBOL;
      stkSymbolOffset = 0L;
      stkCurrentLinenum = 0;
      stkCurrentColumn  = 0;
      stkLinenumIndex   = 0;
   }
   if (ER_ADDRESS_NOT_FOUND == firstErr) {
      return GOOD;   /* don't return error if address not found in symbol
            table */
   }
   if ( err == GOOD ) return GOOD;
   else return firstErr;
}  /* end of StkCalcSymbolicInfo */

/*------------------------------------------------------------------------
** StkGetCurrentFunction
**
** Purpose:
**    Returns the SYM_DESCRIPTOR of the function that contains the current PC
*/
/*------------------------------------------------------------------------*/
RETCODE WINAPI StkGetCurrentFunction(SYM_DESCRIPTOR *currentFunction)  {

   RETCODE err;

   err = StkCalcSymbolicInfo();
   *currentFunction = stkFunctionDesc;
   return err;
}  /* end of StkGetCurrentFunction */


/*------------------------------------------------------------------------
** StkGetCurrentLinenum
**
** Purpose:
**    Returns the SYM_DESCRIPTOR of the lowest level in the symbol table
**    hierarchy that contains the current PC.  This will be a function, block,
**    or label.
*/
/*------------------------------------------------------------------------*/
RETCODE WINAPI
StkGetCurrentLinenum(LINENUM_TYPE       *currentLinenum,
             COLUMN_TYPE        *currentColumn,
             LINENUM_DESCRIPTOR *linenumIndex)  {
   RETCODE err;

   err = StkCalcSymbolicInfo();
   *currentLinenum = stkCurrentLinenum;
   *currentColumn  = stkCurrentColumn;
   *linenumIndex   = stkLinenumIndex;
   return err;
}  /* end of StkGetCurrentLinenum */

/*------------------------------------------------------------------------
** StkGetCurrentLowestlevel
**
** Purpose:
**    Returns the SYM_DESCRIPTOR of the lowest level in the symbol table
**    hierarchy that contains the current PC.  This will be a function, block,
**    or label.
*/
/*------------------------------------------------------------------------*/
RETCODE WINAPI
StkGetCurrentLowestlevel(SYM_DESCRIPTOR *currentLowestLevel,
             U32            *currentSymbolOffset)  {
   RETCODE err;

   err = StkCalcSymbolicInfo();
   *currentLowestLevel  = stkLowestLevelDesc;
   *currentSymbolOffset = stkSymbolOffset;
   return err;
}  /* end of StkGetCurrentLowestLevel */


/*------------------------------------------------------------------------
** StkGetCurrentModule
**
** Purpose:
**    Returns the SYM_DESCRIPTOR of the module that contains the current PC
*/
/*------------------------------------------------------------------------*/
RETCODE WINAPI StkGetCurrentModule(SYM_DESCRIPTOR *currentModule)  {

   RETCODE err;

   err = StkCalcSymbolicInfo();
   *currentModule = stkModuleDesc;
   return err;
}  /* end of StkGetCurrentModule */

//////////////////////////////////////////////////////////////////////////
// Stack Server Routines
//////////////////////////////////////////////////////////////////////////
/*------------------------------------------------------------------------
** stkServer::add
**
** Purpose:
**    Add a stack node to stack link
*/
/*------------------------------------------------------------------------*/
int stkServer::add(struct STKNode *node)
{
    if ( node == 0 ) return (FAILURE);
    if ( curNode == 0 ) {
        curNode = stkListHeader = node ;
    }
    else {
        node->num = curNode->num + 1;
        curNode->next = node;
        node->prev = curNode;
        curNode = node;
    }
    return GOOD;
}

/*------------------------------------------------------------------------
** stkServer::deleteAll
**
** Purpose:
**    delete all stack nodes in stack link
*/
/*------------------------------------------------------------------------*/
void stkServer::deleteAll()
{
    struct STKNode *temp;

    if ( stkListHeader == 0 ) return ;
    temp = curNode = stkListHeader;
    while( curNode ) {
        curNode = curNode->next;
        delete temp;
        temp = curNode;
    }
    stkListHeader = curNode = 0;
    if ( m_buff ) delete m_buff;
    m_buff = 0;
    m_blockDesc = 0;
    m_varDesc = 0;
    return ;
}

/*------------------------------------------------------------------------
** stkServer::buildStack
**
** Purpose:
**    build Stack Server Information
*/
/*------------------------------------------------------------------------*/
#define MAX_STACK_BUFFER 64
#define MIN_STACK_POS    0x20
#define INTER_DATA_RANGE 0xff
#define EXTER_DATA_RANGE 0x10000

#define  BOTTOM_OF_STACK  0xFFFF
int stkServer::buildStack()
{
    RETCODE err;
    if( (!m_isStkDirty)&&(stkListHeader!=0)) return GOOD;
    if(!LdrIsUbrof())
    {
    	if(GOOD!=(err=BSObuildStack() ) ) return err;
    	{   m_isStkDirty=0; return GOOD;}
    }	
    else 
    {
    	if(GOOD!=(err=IARbuildStack() ) ) return err;
    	{   m_isStkDirty=0; return GOOD;}

    }
}

int stkServer::BSObuildStack()
{
    ADDRESS_TYPE     addr;
    U32              currentPC;
    RETCODE          err = GOOD;
    RETCODE          firstErr = GOOD;                                       
    RET_ADDR		 retAddr;
    U32    regValue;
    struct STKNode   *node ,* prevNode;;
    ADDR             start , end;
    SYM_DESCRIPTOR ModuleDesc;
    SYM_DESCRIPTOR FunctionDesc;
    SYM_DESCRIPTOR LowestLevelDesc;  
    
    U16 memArea;                    
    U16 paramBytes, overlayBytes;
    U8 prologBytes;

    U16 ui;
    U32 ul;
    BYTE data[4];
    int nBank;
    
	if (!cpuStatus() ) return GOOD;
	
    deleteAll();
    if ( SrcIsLoaded() != GOOD ) return FAILURE;

    node = new struct STKNode ;
    if ( node == 0 ) return (FAILURE);
    currentPC = 0;

    if (ICE_OK != (err = emuGetReg(0,0,&regValue)))
        return FAILURE;
    
    node->addr1 = (U32) regValue;
    node->addr = (U32) regValue;

// for IAR 
{
    if(ICE_OK != (err = emuGetReg(0,1,&regValue)))   // Get SP
        return FAILURE;
    //node->sp =  regValue;  /* save returned addr from CPU */

    if(regValue >INTER_DATA_RANGE )   memArea=MEM_X0;
    else memArea = MEM_I;

    start.addr = node->sp;
    start.addrType = MEM_I; //3;  // 3 -- IDATA //this will be modified
              
   U16 nFramePtr;
   U32 retOffset;
   BOOL bFrameFlag;
   char funcName[32]; 
   FUNC_CLASS     funcClass;
   U32            stackSize;
   ADDR_RANGE_TYPE codeAddrRange; 
   BOOL bFirstLevel=TRUE;
   U16 nextFrame=0;
    
//  regValue = (unsigned int) node->sp;  
	U16 stkIndex = 0;    
    addr.segType = SEG_CODE;
    while(BOTTOM_OF_STACK>regValue)
    {
        currentPC = node->addr;
        addr.addr = currentPC;

        err = (RETCODE) StackAddrMapBlock(addr.addr,ModuleDesc,
                    FunctionDesc,LowestLevelDesc);
        
        if (GOOD == err)
        {
            if ( FunctionDesc != NULL_SYMBOL )
            {
                node->desc = FunctionDesc;        
                node->desc1 = LowestLevelDesc ;
                node->flag = 0;   
	//new add                   
				if(GOOD!=(err=GetFuncLocalVarBytes(node->desc,overlayBytes) ) )
					return err;
				if(overlayBytes&0x01) overlayBytes++;	
                                
				if(GOOD!=SymGetFuncExt(node->desc,funcName,&funcClass,
				           &stackSize,&codeAddrRange,
				           &nFramePtr,&retOffset,&bFrameFlag,&prologBytes ) )
					return -1;
			    node->bFrame= bFrameFlag;  
			    if(node->bFrame)
			    {	
				    if(bFirstLevel)
				    {
						if(codeAddrRange.startAddr<addr.addr&&
						   codeAddrRange.startAddr +prologBytes>addr.addr)
						{   
						    delete node;
						    return FAILURE;
						}
						else
						{
					    	if(codeAddrRange.startAddr==addr.addr)
					    	{
						    	start.addr=nFramePtr; 
						    	start.addrType= MEM_I; 
							    if ( ICE_OK != emuGetMemN(start,2, (ULPSTR)data,&retAddr) ) {
							        delete node;
							        return FAILURE;
							    }
						    	nextFrame = *((U16*)data);	  
								node->sp= regValue;
								node->framePtr = node->sp - retOffset;
							}
							else
							{
						    	start.addr=nFramePtr; 
						    	start.addrType= MEM_I; 
							    if ( ICE_OK != emuGetMemN(start,2, (ULPSTR)data,&retAddr) ) {
							        delete node;
							        return FAILURE;
							    }
						    	node->framePtr = *((U16*)data);	  
						    	start.addr=node->framePtr; 
						    	start.addrType= (start.addr>INTER_DATA_RANGE)?MEM_X0:MEM_I;; 
							    if ( ICE_OK != emuGetMemN(start,2, (ULPSTR)data,&retAddr) ) {
							        delete node;
							        return FAILURE;
							    }				    	
						    	nextFrame = *((U16*)data);
								node->sp= regValue + overlayBytes + retOffset;
							}
					    }
					    bFirstLevel=FALSE;
					}    
				    else
				    {
						if(nextFrame==0)
						{
					    	start.addr=nFramePtr; 
					    	start.addrType= MEM_I; 
						    if ( ICE_OK != emuGetMemN(start,2, (ULPSTR)data,&retAddr) ) {
						        delete node;
						        return FAILURE;
						    }
					    	node->framePtr =*((U16*)data);	  
					    	start.addr=node->framePtr; 
					    	start.addrType= start.addrType =(addr.addr>INTER_DATA_RANGE)?MEM_X0:MEM_I;; 
						    if ( ICE_OK != emuGetMemN(start,2, (ULPSTR)data,&retAddr) ) {
						        delete node;
						        return FAILURE;
						    }				    	
					    	nextFrame = *((U16*)data);	  
							node->sp= regValue + overlayBytes + retOffset;
                        }
						else
						{				    	
					    	start.addr = nextFrame;
					    	start.addrType =(addr.addr>INTER_DATA_RANGE)?MEM_X0:MEM_I;
						    if ( ICE_OK != emuGetMemN(start,2, (ULPSTR)data,&retAddr) ) {
						        delete node;
						        return FAILURE;
						    }                
						    node->framePtr= nextFrame;
					    	nextFrame =*((U16*)data);	  
					    	node->sp = regValue + overlayBytes +retOffset;
						}
				    }	
			    }
			    else 
			    {
				    if(bFirstLevel)
				    {
						if(codeAddrRange.startAddr<addr.addr&&
						   codeAddrRange.startAddr +prologBytes>addr.addr)
						{   
						    delete node;
						    return FAILURE;
						}
						else
						{
					    	if(codeAddrRange.startAddr==addr.addr)
								node->sp= regValue;
							else
								node->sp= regValue + overlayBytes;
					    }          
					    bFirstLevel=FALSE;
					}    
				    else
				    	node->sp = regValue + overlayBytes ;
			    }
            }
            else if (ModuleDesc != NULL_SYMBOL)
            {
                node->desc = ModuleDesc;
                node->flag = 1;
            }
            else
            {
                delete node;
				
                return FAILURE;
            }
            if ( add( node )!= GOOD) 
            	return FAILURE;
            //node = 0;

            if ( SrcIsStatement() == GOOD )
            {
                char *temp1;   
                HANDLE *pHdl;
                int nExitFlag;
                
                nExitFlag = 0;
                if ( GOOD == SymGetSymbolName(ModuleDesc,&temp1) )
                {
                    if( strcmp(temp1,"CSTARTUP")==0 ) 
                    	nExitFlag = 1;
                    if ( temp1 )
                    {
                        pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
                        GlobalFree( *pHdl );
                    }
                    temp1 = 0;                                   
                    if ( nExitFlag == 1 ) return GOOD;
                }                               
            }
            else
            {
                char *temp1;   
                HANDLE *pHdl;
                int nExitFlag;
                
                nExitFlag = 0;
                if ( GOOD == SymGetSymbolName(FunctionDesc,&temp1) )
                {
                    if( strcmp(temp1,"main")==0 ) nExitFlag = 1;
                    if ( temp1 )
                    {
                        pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
                        GlobalFree( *pHdl );
                    }
                    temp1 = 0;                                   
                    if ( nExitFlag == 1 ) return GOOD;
                }                               
            }       
            
        }
        else {
            delete node;
            return FAILURE;
        }
		prevNode = node;	       
		regValue = node->sp+2;
        node = new struct STKNode;
        if ( node == 0 ) return FAILURE;
		BOOL bBank = TRUE;
	    if(GOOD!=(err=GetFuncParamBytes(prevNode->desc,paramBytes) ))
	    	return err;      
	    if(paramBytes&0x01) paramBytes++;	
	    regValue+=paramBytes;


        if ( LdrSrcSupportBankSwitch() )
        {
			ul = (U32) LdrStkNumConvToBank( (int)ul );
			if ( ul != 0xFFFFFFFFL ) ul--;
		}
		if ( LdrSrcSupportBankSwitch()&& ul < 4 ) 
		{
			bBank=FALSE; 

	        //ul = (ul<<8) + (U8)m_buff[ regValue - 0x09 ];
	        //ul = (ul<<8) + (U8)m_buff[ regValue - 0x0A ];
	        ul = (ul<<8) + (U8)m_buff[ stkIndex+1 ];
	        ul = (ul<<8) + (U8)m_buff[ stkIndex+2 ];
	        
	        stkIndex+=3;
	        regValue += 3;
	        node->sp = regValue;

	        SymConvertToBank(ul, nBank);
	        ui = ( unsigned short ) ul;
	        start.addr = ui - 3;
	        end.addr = ui - 1; 
				        
	        start.addrType = nBank +MEM_P0; // code 
	        if ( ICE_OK != emuGetMemN(start,2,(ULPSTR)data,&retAddr) ) 
	        {
	            delete node;
	            return FAILURE;
	        }               
	        SymConvertToAddr(nBank,ul);
	        node->addr1 = ul; // get caller address
	        
	        if ( data[0] == 0xEF/*0x012*/ ) {   
	            node->addr = ul - 3;   // it is a long call
	        }
	        else {
	            node->addr = ul - 2;   // it is a local call
	        }
		}               
		if ( bBank ) 
		{                     
	        start.addrType =memArea;
	        start.addr = prevNode->sp;
	        if ( ICE_OK != emuGetMemN(start,2,(ULPSTR)data,&retAddr) ) 
	        {
	            delete node;
	            return FAILURE;
	        }  
	      //  U16 uiT;
	      //  uiT = (U16)data[0];
	      //  ui= (U16)data[1];    
	      //  ui= ui<<8 + uiT; 
	        ui =  *((U16*)data);
	        start.addr = ui - 3;
	        start.addrType = end.addrType = MEM_P0 ; // code 
	        if ( ICE_OK != emuGetMemN(start,2,(ULPSTR)data,&retAddr) ) 
	        {
	            delete node;
	            return FAILURE;
	        }
	        node->addr1 = ui;
	        if ( data[0] == (BYTE)(0xEF)/*0x012 */ ) 
	        {
	            node->addr = ui - 3;
	        }
	        else 
	            node->addr = ui - 2;
	    }               
    }

    currentPC = node->addr;
    addr.addr = currentPC;

    err = (RETCODE) StackAddrMapBlock(addr.addr,ModuleDesc,
                FunctionDesc,LowestLevelDesc);
    if (GOOD == err) {
        if ( FunctionDesc != NULL_SYMBOL ) {
            node->desc = FunctionDesc;
            node->desc1 = LowestLevelDesc;
            node->flag = 0;
        }
        else if (ModuleDesc != NULL_SYMBOL) {
            node->desc = ModuleDesc;
            node->flag = 1;
        }
        else {
            delete node;
            return FAILURE;
        }
        if ( add( node )!= GOOD) return FAILURE;
        node = 0;
    }
    else {
        delete node;
        return FAILURE;
    }
}
    return GOOD;
}



int stkServer::IARbuildStack()
{
    ADDRESS_TYPE     addr;
    U32              currentPC;
    RETCODE          err = GOOD;
    RETCODE          firstErr = GOOD;                                       
    RET_ADDR		 retAddr;
    U32    regValue;
    struct STKNode   *node ,* prevNode;;
    ADDR             start , end;
    SYM_DESCRIPTOR ModuleDesc;
    SYM_DESCRIPTOR FunctionDesc;
    SYM_DESCRIPTOR LowestLevelDesc;  
    
    U16 memArea;                    
    U16 paramBytes, overlayBytes,autoBytes;
    U8 prologBytes;

    U16 ui;
    U32 ul;
    BYTE data[4];
    int nBank;
    
	if (!cpuStatus() ) return GOOD;
	
    deleteAll();
    if ( SrcIsLoaded() != GOOD ) return FAILURE;

    node = new struct STKNode ;
    if ( node == 0 ) return (FAILURE);
    currentPC = 0;

    if (ICE_OK != (err = emuGetReg(0,0,&regValue)))
        return FAILURE;
    
    node->addr1 = (U32) regValue;
    node->addr = (U32) regValue;
{
    if(ICE_OK != (err = emuGetReg(0,1,&regValue)))   // Get SP
        return FAILURE;
    //node->sp =  regValue;  /* save returned addr from CPU */
    regValue = regValue&0xffff;
    if(regValue >INTER_DATA_RANGE )   memArea=MEM_X0;
    else memArea = MEM_I;

    start.addr = node->sp;
    start.addrType = MEM_I; //3;  // 3 -- IDATA //this will be modified
              
   U16 nFramePtr;
   U32 retOffset;
   BOOL bFrameFlag;
   char funcName[32]; 
   FUNC_CLASS     funcClass;
   U32            stackSize;
   ADDR_RANGE_TYPE codeAddrRange; 
   BOOL bFirstLevel=TRUE;
   U16 nextFrame=0;
    
//  regValue = (unsigned int) node->sp;  
	U16 stkIndex = 0;    
    addr.segType = SEG_CODE;
    while(BOTTOM_OF_STACK>(regValue&0xffff))
    {
        currentPC = node->addr;
        addr.addr = currentPC;

        err = (RETCODE) StackAddrMapBlock(addr.addr,ModuleDesc,
                    FunctionDesc,LowestLevelDesc);
        
        if (GOOD == err)
        {
            if ( FunctionDesc != NULL_SYMBOL )
            {
                node->desc = FunctionDesc;        
                node->desc1 = LowestLevelDesc ;
                node->flag = 0;   
	//new add                   
				if(GOOD!=(err=IARGetFuncLocalVarBytes(node->desc,overlayBytes,autoBytes) ) )
					return err;
				if(overlayBytes&0x01) overlayBytes++;	
				
		        if(bFirstLevel)
			    {
					switch(FuncFirstLine(ModuleDesc,FunctionDesc, addr.addr) )
					{   
					    case 0: delete node;
					    		return FAILURE; //in the prolog
					    case 1: node->sp= regValue;
								node->framePtr = regValue -overlayBytes-autoBytes;
					    		break;          // in the first line of func
						case 2:	node->sp= regValue + overlayBytes+autoBytes;
								node->framePtr = regValue;
								break;         // out of prolog
				    }
				    bFirstLevel=FALSE;
				}    
			    else
				{
					node->sp= regValue + overlayBytes + autoBytes;
					node->framePtr = regValue;
				}	
            }
            else if (ModuleDesc != NULL_SYMBOL)
            {
                node->desc = ModuleDesc;
                node->flag = 1;
            }
            else
            {
                delete node;
				
                return FAILURE;
            }
            if ( add( node )!= GOOD) 
            	return FAILURE;
            //node = 0;

            if ( SrcIsStatement() == GOOD )
            {
                char *temp1;   
                HANDLE *pHdl;
                int nExitFlag;
                
                nExitFlag = 0;
                if ( GOOD == SymGetSymbolName(ModuleDesc,&temp1) )
                {
                    if( strcmp(temp1,"CSTARTUP")==0 ) 
                    	nExitFlag = 1;
                    if ( temp1 )
                    {
                        pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
                        GlobalFree( *pHdl );
                    }
                    temp1 = 0;                                   
                    if ( nExitFlag == 1 ) return GOOD;
                }                               
            }
            else
            {
                char *temp1;   
                HANDLE *pHdl;
                int nExitFlag;
                
                nExitFlag = 0;
                if ( GOOD == SymGetSymbolName(FunctionDesc,&temp1) )
                {
                    if( strcmp(temp1,"main")==0 ) nExitFlag = 1;
                    if ( temp1 )
                    {
                        pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
                        GlobalFree( *pHdl );
                    }
                    temp1 = 0;                                   
                    if ( nExitFlag == 1 ) return GOOD;
                }                               
            }       
            
        }
        else {
            delete node;
            return FAILURE;
        }
		prevNode = node;	       
		
        node = new struct STKNode;
        if ( node == 0 ) return FAILURE;
		BOOL bBank = TRUE;
	    if(GOOD!=(err=IARGetFuncParamBytes(prevNode->desc,paramBytes) ))
	    	return err;      
	    if(paramBytes&0x01) paramBytes++;	
	    regValue+=paramBytes;

		if ( LdrSrcSupportBankSwitch()) 
		{
			regValue = prevNode->sp+4;
			U16 uiL;
			bBank=FALSE; 
	        start.addrType =memArea;
	        start.addr = prevNode->sp;
	        if ( ICE_OK != emuGetMemN(start,4,(ULPSTR)data,&retAddr) ) 
	        {
	            delete node;
	            return FAILURE;
	        }  
	        uiL = *( (U16*)(&data[2]) );
	        ui =  (*((U16*)data) )&0xFF;
	        ui =  LdrStkNumConvToBank( (int)ui );
	        ul =MAKELONG(uiL,ui);
	        start.addr = uiL - 3;
	        start.addrType = MEM_P0 + ui ; // code 
	        if ( ICE_OK != emuGetMemN(start,2,(ULPSTR)data,&retAddr) ) 
	        {
	            delete node;
	            return FAILURE;
	        }
	        node->addr1 = ul; // get caller address
	        if ( data[0] == 0xEF/*0x012*/ ) {   
	            node->addr = ul - 3;   // it is a long call
	        }
	        else {
	            node->addr = ul - 2;   // it is a local call
	        }
		}               
		if ( bBank ) 
		{                     
	    	regValue = prevNode->sp+2;
	        start.addrType =memArea;
	        start.addr = prevNode->sp;
	        if ( ICE_OK != emuGetMemN(start,2,(ULPSTR)data,&retAddr) ) 
	        {
	            delete node;
	            return FAILURE;
	        }  
	        ui =  *((U16*)data);
	        start.addr = ui - 3;
	        start.addrType = end.addrType = MEM_P0 ; // code 
	        if ( ICE_OK != emuGetMemN(start,2,(ULPSTR)data,&retAddr) ) 
	        {
	            delete node;
	            return FAILURE;
	        }
	        node->addr1 = ui;
	        if ( data[0] == (BYTE)(0xEF)/*0x012 */ ) 
	        {
	            node->addr = ui - 3;
	        }
	        else 
	            node->addr = ui - 2;
	    }               
    }

    currentPC = node->addr;
    addr.addr = currentPC;

    err = (RETCODE) StackAddrMapBlock(addr.addr,ModuleDesc,
                FunctionDesc,LowestLevelDesc);
    if (GOOD == err) {
        if ( FunctionDesc != NULL_SYMBOL ) {
            node->desc = FunctionDesc;
            node->desc1 = LowestLevelDesc;
            node->flag = 0;
        }
        else if (ModuleDesc != NULL_SYMBOL) {
            node->desc = ModuleDesc;
            node->flag = 1;
        }
        else {
            delete node;
            return FAILURE;
        }
        if ( add( node )!= GOOD) return FAILURE;
        node = 0;
    }
    else {
        delete node;
        return FAILURE;
    }
}
    return GOOD;
}



/*------------------------------------------------------------------------
** stkServer::DisplayToShell
**
** Purpose:
**    Display Stack Information to Shell ( As MICEView Back Command )
*/
/*------------------------------------------------------------------------*/
void stkServer::DisplayToShell()
{
    struct STKNode *node;
    char temp[1024];
    int i;
    COMMON_SYMBOL_HEADER  *modPtr , *funcPtr;
    HANDLE *pHdl;
    char *temp1;
    SYM_DESCRIPTOR nextDesc;

    node = stkListHeader ;
    while ( node ) {
        temp1 = 0;
        i = 0;
        sprintf( temp , "    %4x %6lx %6lx ",node->num,node->addr,node->sp );
        i = strlen( temp );
        if ( node->flag == 1 ) {
            if ( GOOD != SymGetSymbolName( node->desc , &temp1 ) )
                return ;
            strcpy( &temp[i] , temp1 );
            i = strlen( temp );
            modPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(node->desc);
            sprintf( &temp[i] , "+%lx " ,( node->addr -
                        modPtr->beginAddrInfo.startAddr ) );
//            if ( GOOD != SymAddGetModuleName( node->desc , &temp[i] ) )
//                return;
            i = strlen( temp );
            strcpy( &temp[i] , temp1 );
            i = strlen( temp );
            if ( temp1 ) {
                pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
                GlobalFree( *pHdl );
            }
            temp1 = 0;
        }
        else {
            nextDesc = node->desc;
            modPtr = 0;
            funcPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(node->desc);
            if ( ((funcPtr->typeIndex.symType)&0x0F) == SYM_FUNCTION ) {
                while ( funcPtr->symParentOffset != NULL_SYMBOL ) {
                    if (!UtilIsValidSymDescriptor( funcPtr->symParentOffset )) {
                        return;
                    }
                    if ( modPtr )
                        nextDesc = modPtr->symParentOffset;
                    modPtr = funcPtr ;
                    funcPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(
                           funcPtr->symParentOffset);
                    if ( ((funcPtr->typeIndex.symType)&0x0F) == SYM_MODULE )
                        break;
                }
                if ( GOOD != SymGetSymbolName( nextDesc , &temp1 ) )
                    return ;
                if ( modPtr == 0 ) modPtr = funcPtr ;
                strcpy( &temp[i] , temp1 );
                if ( temp1 ) {
                    pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
                    GlobalFree( *pHdl );
                }
                temp1 = 0;
                i = strlen( temp );
                sprintf( &temp[i] , "+%lx " ,( node->addr -
                        modPtr->beginAddrInfo.startAddr ) );
                i = strlen( temp );
                if ( GOOD != SymGetSymbolName( modPtr->symParentOffset , &temp1 ) )
                    return ;
                strcpy( &temp[i] , temp1 );
                if ( temp1 ) {
                    pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
                    GlobalFree( *pHdl );
                }
                temp1 = 0;
                i = strlen( temp );
                temp[i] = ' ';
                if ( GOOD != DisplayParameters(node->addr,nextDesc,&temp[i+1]) )
                    return;
            }
//          SymShowLine( temp );
//          node = node->next;
        }
        SymShowLine( temp );
        node = node->next;
    }
    return ;
}

/*------------------------------------------------------------------------
** DisplayParameters
**
** Purpose:
**    Display Stack Function Parameters Information to String
*/
/*------------------------------------------------------------------------*/
int DisplayParameters(U32 addr,SYM_DESCRIPTOR desc , char* tmpStr)
{
   HPU8             symPtr;
//   S8               tmpStr[1024]; // used for type names
   S8               temp[256];
   TYPE_HEADER_TYPE typeHeader;
//   TYPE_INDEX       typeIndex;
   int              n;                  
   SYM_DESCRIPTOR   symbol;
   COMMON_SYMBOL_HEADER  *modPtr ;
    HANDLE *pHdl;
    char *temp1;

   symPtr = (HPU8)st.GetHugeDataPtr(desc);

   // get symbol type index
   if ( (((COMMON_SYMBOL_HEADER *)symPtr)->typeIndex.symType&0xF)
        !=SYM_FUNCTION ) 
        return FAILURE;
         // insert the return type name
         // assign the string pointer in typeHeader to the local string
    typeHeader.typeName = temp;

    U32 attribute;
    U8  frameType;
    U32 pushMask;                                             
    U16 listCount;
    U8  argCount;
    U8  level;
    U8  fatherName[256];
//    TYPE_INDEX returnIndexType;
         
    if (GOOD == SymGetFuncType( desc,
                                &attribute,
                                &frameType,
                                &pushMask,
                                &typeHeader,  // contains tmpStr ptr
                                &argCount,
                                &level,
                                (LPSTR)fatherName)) {
            // tmpStr filled in with simple name or null
            
        memset( tmpStr , 0 , 512 );   
         
//        sprintf(tmpStr,"(");                    
//        n = strlen(tmpStr);
        if ( GOOD != SymGetFuncVarHeadList(desc,&symbol,&listCount) )
            return FAILURE;
            
        if ( listCount < argCount ) return FAILURE;
         
        if ( GOOD != SrcIsStatement() )
            while ( listCount > argCount ) {
                if (!UtilIsValidSymDescriptor( symbol )) {
                    return FAILURE;
                }
                modPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(symbol);
                symbol = modPtr->symSiblingOffset;
                listCount--;
            }
        else 
            listCount = argCount;
                     
        if ( GOOD != SymGetSymbolName( desc , &temp1 ) )
            return FAILURE;    

        if ( GOOD == SrcIsStatement() ) {
            U32 uAddr , uStart , uEnd;
    
            uStart = 0xFFFFFFFFL;
            uEnd = 0;       
            uAddr=(U16)((COMMON_SYMBOL_HEADER *)symPtr)->beginAddrInfo.startAddr;
            SymSrcGetStatementRange(uAddr,uStart,uEnd);
            if ( ( addr>=uStart ) &&  ( addr<=uEnd ) ) {
                sprintf( tmpStr,"%s(...)",temp1 );
                return GOOD;
            }
        }                  
        sprintf(tmpStr,"%s(",temp1);                    
        n = strlen(tmpStr);
        if ( temp1 ) {
            pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
            GlobalFree( *pHdl );
        }
        while ( listCount ) {
            if (!UtilIsValidSymDescriptor( symbol )) {
                return FAILURE;
            }
            if ( DisplayOneParameter( symbol , &tmpStr[n] ) != GOOD )
                break;
            n = strlen( tmpStr );   
            modPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(symbol);
            symbol = modPtr->symSiblingOffset;
            listCount--;
        }
         
        n = strlen( tmpStr );
        if ( tmpStr[ n-1 ] == ',' ) tmpStr[n-1]=')';
        else tmpStr[n]=')';     
    }
    else 
        return FAILURE;
         

         // get the type header info of the type
//         if (GOOD != (err = SymGetTypeHeader(typeIndex, &typeHeader))) 
//            goto CLEANUP;
    return GOOD;
}

/*------------------------------------------------------------------------
** DisplayOneParameter
**
** Purpose:
**    Display Stack Function One Parameter Information to String
*/
/*------------------------------------------------------------------------*/
int DisplayOneParameter(SYM_DESCRIPTOR desc , char* tmpStr)
{
//   HPU8             symPtr;
   S8               temp[256];
   TYPE_HEADER_TYPE typeHeader;
   TYPE_INDEX       typeIndex;
//   int              n;                  
   RETCODE          err;
//   SYM_DESCRIPTOR symbol;
//   COMMON_SYMBOL_HEADER  *modPtr ;
   VAR_STORAGE_CLASS   storageClass;
   VAR_REGISTER_CLASS  registerClass;
   BOOLEAN             isConstant;
   SYM_DESCRIPTOR      funcDescriptor;
   SYM_DESCRIPTOR      moduleDescriptor;
   SYM_DESCRIPTOR      parentDescriptor;
   GET_VAR_ADDR_STRUCT varAddr;                                       
   RET_ADDR retAddr;

    if ( GOOD != SymGetVar( desc,
                            temp,
                            &typeIndex,
                            &storageClass,
                            &registerClass,
                            &isConstant,
                            &funcDescriptor,
                            &moduleDescriptor,
                            &parentDescriptor,
                            &varAddr) )
          return FAILURE;

   // get symbol type index
   if ( storageClass != STATIC_VAR_CLASS ) return FAILURE;
         // insert the return type name
         // assign the string pointer in typeHeader to the local string
    typeHeader.typeName = temp;

    if (GOOD != (err = SymGetTypeHeader(typeIndex, &typeHeader))) 
        return FAILURE;
    if ( registerClass == NOT_REG ) {
        if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS ) {
            return ( BuildSimpleValue( typeIndex , varAddr.fixedAddr.segType ,
                     varAddr.fixedAddr.startAddr , tmpStr ) );
        }
        else {
            if ( typeHeader.t.complexType == TY_TYPE ) {
                while( 1 ) {
                    TYPE_INDEX       typeNext;
                   
                    if ( GOOD != SymGetTypeTypeIndex(typeIndex,&typeNext) )
                        return FAILURE;
                    typeIndex = typeNext;
                    if (GOOD != (err = SymGetTypeHeader(typeIndex, &typeHeader))) 
                        return FAILURE;
                    if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS )
                        break;
                    else if ( typeHeader.t.complexType != TY_TYPE )
                        break;
                }   
                if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS ) {
                    return ( BuildSimpleValue( typeIndex , varAddr.fixedAddr.segType ,
                             varAddr.fixedAddr.startAddr , tmpStr ) );
                }
            }

            if ( typeHeader.t.complexType == TY_BITFIELD ) {
                if ( SrcIsIEEE() == GOOD ) {
                    struct VarNode node;
                    node.father = 0;
                    node.typeIndex = typeIndex;
                    node.addr.addr = varAddr.fixedAddr.startAddr;
                    node.addr.segType = varAddr.fixedAddr.segType;
                    return (BuildIEEEBValue(&node,0,tmpStr));
                }
                else {
                    return ( BuildBitValue(typeIndex,varAddr.fixedAddr.segType,
                        varAddr.fixedAddr.startAddr, tmpStr ) );
                }
            }
            if ( typeHeader.typeChoice == COMPLEX_TYPE_CLASS )
            switch(typeHeader.t.complexType) {
            case TY_ENUM_C :
                return ( BuildEnumValue( typeIndex,varAddr.fixedAddr.segType ,
                     varAddr.fixedAddr.startAddr , 0 ,tmpStr ) );
            case TY_SMALL_PTR :
                if ( typeHeader.sizeCalculated == TRUE ) {
                    ADDR    start , end;
                    char    data[16];
                    U32     address ;
                    SEGMENTTYPE segType;

                    address = 0;
                    ConvEnumToAbiType( varAddr.fixedAddr.segType ,
                                 start.addrType );
                    end.addrType = start.addrType;
                    start.addr = varAddr.fixedAddr.startAddr;
                    end.addr = start.addr+
                               (typeHeader.sizeInMAUs - 1);
#ifdef _LINK_WITH_ABI_
                    if ( ICE_OK != emuGetMemN(start,(U16)(end.addr-start.addr+1),(ULPSTR)data,&retAddr) ) {
                        return FAILURE;
                    } 
#else
					data[0] = 0;
					data[1] = 0;
					data[2] = 0;
#endif  
                    if ( typeHeader.sizeInMAUs == 3 ) {
                        address = (U8) data[1];
                        address = (address<<8) + (U8)data[2];
                        if ( GOOD == SrcIsStatement() ) {
                            UbrofConvPtrToSeg(data[0],segType);
                        }
                        else {
                            Omf51ConvPtrToSeg(data[0],segType);
                        }
                        return ( BuildComplexAddr( segType ,
                            address ,tmpStr ) );
                    }
                    else if ( typeHeader.sizeInMAUs == 2 ) {
                        address = (U8) data[0];
                        address = (address<<8) + (U8)data[1];
                        return ( BuildComplexAddr( varAddr.fixedAddr.segType ,
                            address ,tmpStr ) );
                    }
                    else if ( typeHeader.sizeInMAUs == 1 ) {
                        address = (U8) data[0];
                        return ( BuildComplexAddr( varAddr.fixedAddr.segType ,
                            address ,tmpStr ) );
                    }
                }
                return ( BuildComplexAddr( varAddr.fixedAddr.segType ,
                        varAddr.fixedAddr.startAddr ,tmpStr ) );
            case TY_OMF51_PTR :
                if ( typeHeader.sizeCalculated == TRUE ) {
                    ADDR    start , end;
                    char    data[16];
                    U32     address ;
                    SEGMENTTYPE segType;
                    TYPE_OMF51_PTR_STRUCT omf51Ptr;

                    if ( SymGetTypePointer51(typeIndex,&omf51Ptr) != GOOD )
                        return FAILURE;
                    address = 0;
                    ConvEnumToAbiType( varAddr.fixedAddr.segType ,
                                 start.addrType );
                    end.addrType = start.addrType;
                    start.addr = (U16) varAddr.fixedAddr.startAddr;
                    end.addr = start.addr+
                               (U16)(typeHeader.sizeInMAUs - 1);
#ifdef _LINK_WITH_ABI_
                    if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr) ) {
                        return FAILURE;
                    }
#else
					data[0] = 0;
					data[1] = 0;
					data[2] = 0;
#endif  
                    if ( typeHeader.sizeInMAUs == 3 ) {
                        address = (U8) data[1];
                        address = (address<<8) + (U8)data[2];
                        if ( GOOD == SrcIsStatement() ) {
                            UbrofConvPtrToSeg(data[0],segType);
                        }
                        else {
                            Omf51ConvPtrToSeg(data[0],segType);
                        }
                        return ( BuildComplexAddr( segType ,
                            address ,tmpStr ) );
                    }
                    else if ( typeHeader.sizeInMAUs == 2 ) {
                        address = (U8) data[0];
                        address = (address<<8) + (U8)data[1];
                        MemoryTypeConvToSeg( omf51Ptr.memSpace,segType );
                        return ( BuildComplexAddr( segType ,
                            address ,tmpStr ) );
                    }
                    else if ( typeHeader.sizeInMAUs == 1 ) {
                        address = (U8) data[0];
                        MemoryTypeConvToSeg( omf51Ptr.memSpace,segType );
                        return ( BuildComplexAddr( segType ,
                            address ,tmpStr ) );
                    }
                }
                return ( BuildComplexAddr( varAddr.fixedAddr.segType ,
                        varAddr.fixedAddr.startAddr ,tmpStr ) );
            default :
                return ( BuildComplexAddr( varAddr.fixedAddr.segType ,
                        varAddr.fixedAddr.startAddr ,tmpStr ) );
            }
        }
    }
    else {
        sprintf( tmpStr,"Register," ); 
    }
    return GOOD;
}

/*------------------------------------------------------------------------
** BuildSimpleValue
**
** Purpose:
**    Build build-in types value to String
*/
/*------------------------------------------------------------------------*/
int BuildSimpleValue(TYPE_INDEX typeIndex,SEGMENTTYPE type,U32 addr,char* str )
{                                                              
    ADDR             start , end;
    char data[16] ;
    char data1[8];
    U8 uc;
    U16 ui;
    U32 ul;
    float *f_p;
    double *d_p;                                                        
    RET_ADDR retAddr;
    int i;
    
    if ( typeIndex >= 256 ) return FAILURE;
    switch( type ) {
    case SEG_CODE :  
    	{   
    		int nBank;
    		SymConvertToBank( addr , nBank );
        	start.addrType = end.addrType = MEM_P0+nBank;
        }    
//        start.addrType = end.addrType = 2;
        break;
    case SEG_DATA :
        start.addrType = end.addrType = MEM_I;//4;
        break;
    case SEG_XDATA :                            
    	{   
    		int nBank;
    		SymConvertToBank( addr , nBank );
        	start.addrType = end.addrType = MEM_X0+nBank;
        }    
    
        //start.addrType = end.addrType = 3;
        break;
    case SEG_BIT :
        start.addrType = end.addrType = 6;
        break;
    case SEG_REGISTER :
        start.addrType = end.addrType = 5;
        break;
    case SEG_SFR :
        start.addrType = end.addrType = 7;
        break;
    default :
        start.addrType = end.addrType = 0;
        break;
    }   
    start.addr = addr ;
    switch ( typeIndex ) {
    case BI_BIT :
        end.addr = start.addr ;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
#endif  
        uc = data[0]; 
        sprintf(str,"%u,",((U16)uc));
        return GOOD;
    
    case BI_S8_SCHAR:
    case BI_U8_UCHAR:
    case BI_S8_CHAR:
        end.addr = start.addr ;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
#endif  
        if( typeIndex == BI_U8_UCHAR ) {            
            uc = data[0]; 
//            if ( (uc>=0x80)||(uc==0) )
//                sprintf(str,"%u,",((U16)uc));
//            else 
//                sprintf(str,"'%c',",uc);
            if ( (uc>=0x20)&&(uc<=0x7F) )
                sprintf(str,"'%c',",uc);
            else
                sprintf(str,"%u,",((U16)uc));
        }
        else {
//            if ( data[0] <= 0 )
//                sprintf(str,"%d,",data[0]);
//            else 
//                sprintf(str,"'%c',",data[0]);
            if ( (data[0]>=0x20)&&(data[0]<=0x7F) )
                sprintf(str,"'%c',",data[0]);
            else
                sprintf(str,"%d,",data[0]);
        }
        return GOOD;
    case BI_S16_SINT:
    case BI_U16_UINT:
    case BI_S16_SHORT:
    case BI_S16_USHORT:
    case BI_S16_SHORTINT:
    case BI_S16_SSHORT:

    case BI_STACK_INT:
    case BI_STACK_U:
    case BI_STACK_UINT:
        end.addr = start.addr+1;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
#endif  
        //ui = (U16) data[0];
        //ui = (ui<<8) + (U8)data[1];
        ui=*((U16*)data); // jerry
//        if ( typeIndex==BI_U16_UINT || typeIndex==BI_S16_USHORT ) {
        if ( typeIndex==BI_U16_UINT || typeIndex==BI_S16_USHORT ||
            typeIndex==BI_STACK_U || typeIndex==BI_STACK_UINT ) {
            sprintf(str,"%u,",ui);
        }
        else {
            sprintf(str,"%d,",(int)ui);
        }
        return GOOD;
    case BI_S32_SLONG:
    case BI_U32_ULONG:
    case BI_S32_LONG:
        end.addr = start.addr+3;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
        data[2] = 0;
        data[3] = 0;
#endif  
        //ul = (U8) data[0];
        //ul = (ul<<8) + (U8)data[1];
        //ul = (ul<<8) + (U8)data[2];
        //ul = (ul<<8) + (U8)data[3];
        ul=*((U32*)data);
        if ( typeIndex==BI_U32_ULONG ) {
            sprintf(str,"%luL,",ul);
        }
        else {
            sprintf(str,"%ldL,",(long)ul);
        }
        return GOOD;
    case BI_F32 :
        end.addr = start.addr+3;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr)) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
        data[2] = 0;
        data[3] = 0;
#endif  
        if ( 0/*GOOD == SrcIsStatement() || GOOD == SrcIsIEEE()*/ )
            for ( i=0;i<4;i++ ) {
                data1[3-i] = data[i];
            }
        else
            for ( i=0;i<4;i++ ) {
                data1[i] = data[i];
            }
        f_p = (float *)data1;
//      f_p = (float *)data;
//      sprintf(str,"%f,",*f_p);
        sprintf(str,"%e,",*f_p);
        return GOOD;
    case BI_F64 :    
        if ( 0/*GOOD == SrcIsStatement() || GOOD == SrcIsIEEE() */) {
            end.addr = start.addr+3;
#ifdef _LINK_WITH_ABI_        
            if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr)) {
                return FAILURE;
            }
#else 
            data[0] = 0;    
            data[1] = 0;
            data[2] = 0;
            data[3] = 0;
#endif  
            for ( i=0;i<4;i++ ) {
                data1[3-i] = data[i];
            }
            f_p = (float *)data1;
    //      f_p = (float *)data;
    //      sprintf(str,"%f,",*f_p);
            sprintf(str,"%e,",*f_p);
        }
        else {
            end.addr = start.addr+7;
#ifdef _LINK_WITH_ABI_        
            if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr) ) {
                return FAILURE;
            }
#endif  
//          if ( GOOD == SrcIsStatement() )
//              for ( i=0;i<8;i++ ) {
//                  data1[7-i]=data[i];
//              }
//          else    
            for ( i=0;i<8;i++ ) {
                data1[i] = data[i];
            }
            d_p = (double *)data1;
    //      d_p = (double *)data;
    //      sprintf(str,"%lf,",*d_p);
            sprintf(str,"%le,",*d_p);
        }
        return GOOD;
    default :
        end.addr = start.addr ;
        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr) ) {
            return FAILURE;
        }
        uc = data[0]; 
        sprintf(str,"%d,",((U16)uc));
        return GOOD;
    }
    return GOOD;        
}

/*------------------------------------------------------------------------
** BuildBitValue
**
** Purpose:
**    Build bitfield type value to String
*/
/*------------------------------------------------------------------------*/
int BuildBitValue(TYPE_INDEX typeIndex,
        SEGMENTTYPE type,U32 addr,char* str )
{                                                              
    TYPE_HEADER_TYPE typeHeader;
    TYPE_BITFIELD_STRUCT bit;
    ADDR             start , end;
    char data[16] ;
    char temp[256];
    U16 ui , uj;
    int i;           
    RET_ADDR retAddr;
    
//    if ( typeIndex >= 256 ) return FAILURE;
    typeHeader.typeName = temp;
    if (GOOD != SymGetTypeHeader(typeIndex, &typeHeader)) 
        return FAILURE;
    if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS )
        return FAILURE;
    if ( typeHeader.t.complexType != TY_BITFIELD ) 
        return FAILURE;
    switch( type ) {
    case SEG_CODE : 
        {   
    		int nBank;
    		SymConvertToBank( addr , nBank );
        	start.addrType = end.addrType = MEM_P0+nBank;
        }
        //start.addrType = end.addrType = 2;
        break;
    case SEG_DATA :
        start.addrType = end.addrType = MEM_I;//4;
        break;
    case SEG_XDATA :                            
    	{   
    		int nBank;
    		SymConvertToBank( addr , nBank );
        	start.addrType = end.addrType = MEM_X0+nBank;
        }    
        //start.addrType = end.addrType = 3;
        break;
    case SEG_BIT :
        start.addrType = end.addrType = 6;
        break;
    case SEG_REGISTER :
        start.addrType = end.addrType = 5;
        break;
    case SEG_SFR :
        start.addrType = end.addrType = 7;
        break;
    default :
        start.addrType = end.addrType = 0;
        break;
    }   
    start.addr = addr ;
    if ( GOOD != SymGetTypeBitfield(typeIndex,&bit) )
        return FAILURE;
        
    switch ( bit.baseTypeIndex ) {
    case BI_S8_SCHAR:
    case BI_U8_UCHAR:
    case BI_S8_CHAR:  
        if ( (bit.offset+bit.size)>8 ) return FAILURE;
        end.addr = start.addr ;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr)) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
#endif  
        ui = data[0];
//      for( i=0;i < bit.offset;i++)
//          ui = ui>>1;
        ui = ui >> bit.offset ;
        uj = 1;
        for(i=0;((U16)i)<bit.size;i++)
            uj = uj << 1;
        uj--;
        ui = ui & uj;
        if( bit.baseTypeIndex == BI_U8_UCHAR ) {            
//        if( typeIndex == BI_U8_UCHAR ) {            
//            if ( (ui>=0x80)||(ui==0) )
//                sprintf(str,"%u,",ui);
//            else 
//                sprintf(str,"'%c',",(unsigned char)ui);
            if ( (ui>=0x20)&&(ui<=0x7F) ) 
                sprintf(str,"'%c',",(unsigned char)ui);
            else
                sprintf(str,"%u,",ui);
        }
        else {         
            uj++;
            if ( ui >= uj/2 )
                i = (int)(ui-uj);
            else
                i = (int)ui;
//            if ( i <= 0 )
//                sprintf(str,"%d,",i);
//            else 
//                sprintf(str,"'%c',",(char)i);
            if ( (i>=0x20)&&(i<=0x7F) )
                sprintf(str,"'%c',",(char)i);
            else
                sprintf(str,"%d,",i);
        }
        return GOOD;
    case BI_S16_SINT:
    case BI_U16_UINT:
    case BI_S16_SHORT:
    case BI_S16_USHORT:
    case BI_S16_SHORTINT:
    case BI_S16_SSHORT:

    case BI_STACK_INT:
    case BI_STACK_U:
    case BI_STACK_UINT:
        if ( (bit.offset+bit.size)>16 ) return FAILURE;
        end.addr = start.addr+1;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
#endif  
        //ui = (U16) data[0];
        //ui = (ui<<8) + (U8)data[1];
        ui=*((U16*)data);
        ui = ui >> bit.offset ;
        uj = 1;
        for(i=0;(U16)i<bit.size;i++)
            uj = uj << 1;
        uj--;
        ui = ui & uj;

        if ( bit.baseTypeIndex==BI_U16_UINT ||
//             bit.baseTypeIndex==BI_S16_USHORT ) {
             bit.baseTypeIndex==BI_S16_USHORT || 
             bit.baseTypeIndex==BI_STACK_U ||
             bit.baseTypeIndex==BI_STACK_UINT ) {
//        if ( typeIndex==BI_U16_UINT || typeIndex==BI_S16_USHORT ) {
            sprintf(str,"%u,",ui);
        }
        else {              
            uj++;
            if (ui >= uj/2)
                i = (int)(ui-uj);
            else 
                i = ui;
            sprintf(str,"%d,",(int)i);
        }
        return GOOD;
    default : // U16 ;
        if ( (bit.offset+bit.size)>16 ) return FAILURE;
        end.addr = start.addr+1;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
#endif  
        //ui = (U16) data[0];
        //ui = (ui<<8) + (U8)data[1];
        ui =*((U16*)data);
        
        ui = ui >> bit.offset ;
        uj = 1;
        for(i=0;(U16)i<bit.size;i++)
            uj = uj << 1;
        uj--;
        ui = ui & uj;

        sprintf(str,"%u,",ui);
        return GOOD;
    }
    return GOOD;        
}

/*------------------------------------------------------------------------
** BuildComplexValue
**
** Purpose:
**    Build complex types value to String
*/
/*------------------------------------------------------------------------*/
int BuildComplexAddr( SEGMENTTYPE type , U32 addr , char* str )
{
    int nBank;
    switch( type ) {
    case SEG_CODE :  
    	SymConvertToBank(addr,nBank);
        //if ( nBank<=9&&nBank>=6 ) {
        	sprintf( str, "P%d:", (int)(nBank) );
        //}    
        // sprintf( str , "P:" );
        break;
    case SEG_DATA :
        sprintf( str , "I:" );
        break;
    case SEG_XDATA : 
	    SymConvertToBank(addr,nBank);
        //if ( nBank<=9&&nBank>=6 ) {
       	sprintf( str, "X%d:", (int)(nBank) );

        //sprintf( str , "X:" );
        break;
    case SEG_BIT :
        sprintf( str , "B:" );
        break;
    case SEG_REGISTER :
        sprintf( str , "R:" );
        break;         
    case SEG_SFR :
    	sprintf( str , "S:" );
    	break;
    default :
        sprintf( str , "U:" );
        break;
    }
    U16ToStr( (U16)addr , &str[strlen(str)] );
    str[8] = ',';
    return GOOD;    
}

/*------------------------------------------------------------------------
** BuildSValue
**
** Purpose:
**    Build build-in types value to String for variable server
*/
/*------------------------------------------------------------------------*/
int BuildSValue(TYPE_INDEX typeIndex,SEGMENTTYPE type,U32 addr,char* str,
					int nSize=0 ,int offset=0)
{                                                              
    ADDR             start , end;
    char data[16] ;
    char data1[8];
    U8 uc;
    U16 ui;
    U32 ul;
    float *f_p;
    double *d_p;
    int i;          
    RET_ADDR retAddr;
    offset = offset%8;
    if ( typeIndex >= 256 ) return FAILURE;
    switch( type ) {
    case SEG_CODE :      
    	{   
    		int nBank;
    		SymConvertToBank( addr , nBank );
        	start.addrType = end.addrType = MEM_P0+nBank;
        }    
        //start.addrType = end.addrType = 2;
        break;
    case SEG_DATA :
        start.addrType = end.addrType = MEM_I;//4;
        break;
    case SEG_XDATA :
    	{   
    		int nBank;
    		SymConvertToBank( addr , nBank );
        	start.addrType = end.addrType = MEM_X0+nBank;
        }        
        //start.addrType = end.addrType = 3;
        break;
    case SEG_BIT :
        start.addrType = end.addrType = 6;
        break;
    case SEG_REGISTER :
        start.addrType = end.addrType = 5;
        break;
    case SEG_SFR :
        start.addrType = end.addrType = 7;
        break;
    default :
        start.addrType = end.addrType = 0;
        break;
    }   
    start.addr = addr ;
    switch ( typeIndex ) {
    case BI_BIT :
        end.addr = start.addr ;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,(U16)(end.addr-start.addr+1),(ULPSTR)data,&retAddr) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
#endif  
        uc = data[0]; 
//        sprintf(str,"%u",((U16)uc));
        sprintf(str,"%u ",((U16)uc));
//        sprintf(str,"%u (0x%x)",((U16)uc),((U16)uc));
        VarU8ToStr(uc,&str[strlen(str)] );
        return GOOD;
    case BI_S8_SCHAR:
    case BI_U8_UCHAR:
    case BI_S8_CHAR:
        end.addr = start.addr ;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
#endif   
        if(nSize!=0)
        {
        	BYTE mask=((1<<nSize)-1)<<offset;
        	data[0] = ( data[0]&mask )>>offset; 
        }

        if( typeIndex == BI_U8_UCHAR ) {            
            uc = data[0]; 
//            if ( (uc>=0x20)&&(uc<=0x7F) ) 
//                sprintf(str,"'%c'",uc);
//                sprintf(str,"'%c' (0x%x)",uc,uc);
//            else
//                sprintf(str,"%u",((U16)uc));
//                sprintf(str,"%u (0x%x)",((U16)uc),((U16)uc));
            if ( (uc>=0x20)&&(uc<=0x7F) ) 
//                sprintf(str,"'%c'",uc);
                sprintf(str,"'%c' ",uc);
//                sprintf(str,"'%c' (0x%x)",uc,uc);
            else
//                sprintf(str,"%u",((U16)uc));
                sprintf(str,"%u ",((U16)uc));
//                sprintf(str,"%u (0x%x)",((U16)uc),((U16)uc));
            VarU8ToStr(uc,&str[strlen(str)] );
        }
        else {
//            if( (data[0]>=0x20)&&(data[0]<=0x7F) )
//                sprintf(str,"'%c'",data[0]);
//                sprintf(str,"'%c' (0x%x)",data[0],data[0]);
//            else
//                sprintf(str,"%d",data[0]);
//                sprintf(str,"%d (0x%x)",data[0],data[0]);
            if( (data[0]>=0x20)&&(data[0]<=0x7F) )
//                sprintf(str,"'%c'",data[0]);
                sprintf(str,"'%c' ",data[0]);
//                sprintf(str,"'%c' (0x%x)",data[0],data[0]);
            else
//                sprintf(str,"%d",data[0]);
                sprintf(str,"%d ",data[0]);
//                sprintf(str,"%d (0x%x)",data[0],data[0]);
            VarU8ToStr(data[0],&str[strlen(str)] );
        }           
        return GOOD;
    case BI_S16_SINT:
    case BI_U16_UINT:
    case BI_S16_SHORT:
    case BI_S16_USHORT:
    case BI_S16_SHORTINT:
    case BI_S16_SSHORT:

    case BI_STACK_INT:
    case BI_STACK_U:
    case BI_STACK_UINT:
        end.addr = start.addr+1;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
#endif  
        //ui = (U16) data[0];
        //ui = (ui<<8) + (U8)data[1];
        ui=*((U16*)data);
        if(nSize!=0)
        {
        	U16 mask =( (1<<nSize)-1)<<offset;
        	ui = (ui&mask)>>offset;
        }
        
//        if ( typeIndex==BI_U16_UINT || typeIndex==BI_S16_USHORT ) {
//            sprintf(str,"%u",ui);
//            sprintf(str,"%u (0x%x)",ui,ui);
//        }
//        else {
//            sprintf(str,"%d",(int)ui);
//            sprintf(str,"%d (0x%x)",(int)ui,ui);
//        }
//        if ( typeIndex==BI_U16_UINT || typeIndex==BI_S16_USHORT ) {
        if ( typeIndex==BI_U16_UINT || typeIndex==BI_S16_USHORT ||
            typeIndex==BI_STACK_U || typeIndex==BI_STACK_UINT ) {
//            sprintf(str,"%u",ui);
            sprintf(str,"%u ",ui);
//            sprintf(str,"%u (0x%x)",ui,ui);
            VarU16ToStr(ui,&str[strlen(str)] );
        }
        else {
//            sprintf(str,"%d",(int)ui);
            sprintf(str,"%d ",(int)ui);
//            sprintf(str,"%d (0x%x)",(int)ui,ui);
            VarU16ToStr(ui,&str[strlen(str)] );
        }
        return GOOD;
    case BI_S32_SLONG:
    case BI_U32_ULONG:
    case BI_S32_LONG:
        //end.addr = start.addr+3;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,4,(ULPSTR)data,&retAddr) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
        data[2] = 0;
        data[3] = 0;
#endif                     
		
        ul = *( (U32*)data);
        if(nSize!=0)
        {
        	U32 mask =( ((1<<nSize)-1)<<offset);
        	ul=(ul&mask)>>offset;
        }
        //ul = (ul<<8) + (U8)data[1];
        //ul = (ul<<8) + (U8)data[2];
        //ul = (ul<<8) + (U8)data[3];
//        if ( typeIndex==BI_U32_ULONG ) {
//            sprintf(str,"%luL",ul);
//            sprintf(str,"%luL (0x%lx)",ul,ul);
//        }
//        else {
//            sprintf(str,"%ldL",(long)ul);
//            sprintf(str,"%ldL (0x%lx)",(long)ul,(long)ul);
//        }
        if ( typeIndex==BI_U32_ULONG ) {
//            sprintf(str,"%luL",ul);
            sprintf(str,"%luL ",ul);
//            sprintf(str,"%luL (0x%lx)",ul,ul);
            VarU32ToStr(ul,&str[strlen(str)] );
        }
        else {
//            sprintf(str,"%ldL",(long)ul);
            sprintf(str,"%ldL ",(long)ul);
//            sprintf(str,"%ldL (0x%lx)",(long)ul,(long)ul);
            VarU32ToStr(ul,&str[strlen(str)] );
        }
        return GOOD;
    case BI_F32 :
        end.addr = start.addr+3;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,(U16)(4),(ULPSTR)data,&retAddr) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
        data[2] = 0;
        data[3] = 0;
#endif  
        if ( 0/*GOOD == SrcIsStatement() || GOOD == SrcIsIEEE()*/ )
            for ( i=0;i<4;i++ ) {
                data1[3-i] = data[i];
            }
        else
            for ( i=0;i<4;i++ ) {
                data1[i] = data[i];
            }
        f_p = (float *)data1;
//      f_p = (float *)data;
//      sprintf(str,"%f,",*f_p);
        sprintf(str,"%e",*f_p);
        return GOOD;
    case BI_F64 :    
        if ( 0/*GOOD == SrcIsStatement() || GOOD == SrcIsIEEE() */) {
            end.addr = start.addr+3;
#ifdef _LINK_WITH_ABI_        
            if ( ICE_OK !=emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr) ) {
                return FAILURE;
            }
#else 
            data[0] = 0;    
            data[1] = 0;
            data[2] = 0;
            data[3] = 0;
#endif  
            for ( i=0;i<4;i++ ) {
                data1[3-i] = data[i];
            }
            f_p = (float *)data1;
    //      f_p = (float *)data;
    //      sprintf(str,"%f,",*f_p);
            sprintf(str,"%e",*f_p);
        }
        else {
            end.addr = start.addr+7;
#ifdef _LINK_WITH_ABI_        
            if ( ICE_OK !=emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr)) {
                return FAILURE;
            }
#endif  
//          if ( GOOD == SrcIsStatement() )
//              for ( i=0;i<8;i++ ) {
//                  data1[7-i]=data[i];
//              }
//          else    
            for ( i=0;i<8;i++ ) {
                data1[i] = data[i];
            }
            d_p = (double *)data1;
    //      d_p = (double *)data;
    //      sprintf(str,"%lf,",*d_p);
            sprintf(str,"%le",*d_p);
        }
        return GOOD;
    default :
        end.addr = start.addr ;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
#endif  
        uc = data[0]; 
        if(nSize!=0)
        {
        	BYTE mask =( ((1<<nSize)-1)<<offset );
        	uc=(uc&mask)>>offset;
        }
//        sprintf(str,"%d",((U16)uc));
        sprintf(str,"%d ",((U16)uc));
//        sprintf(str,"%d (0x%x)",((U16)uc),uc);
        VarU8ToStr(uc,&str[strlen(str)] );
        return GOOD;
    }
    return GOOD;        
}

/*------------------------------------------------------------------------
** BuildBValue
**
** Purpose:
**    Build bitfield type value to String for variable server
*/
/*------------------------------------------------------------------------*/
int BuildBValue(TYPE_INDEX typeIndex,
        SEGMENTTYPE type,U32 addr,char* str )
{                                                              
    TYPE_HEADER_TYPE typeHeader;
    TYPE_BITFIELD_STRUCT bit;
    ADDR             start , end;
    char data[16] ;
    char temp[256];
    U16 ui , uj;
    int i;       
    RET_ADDR  retAddr;
    
//    if ( typeIndex >= 256 ) return FAILURE;
    typeHeader.typeName = temp;
    if (GOOD != SymGetTypeHeader(typeIndex, &typeHeader)) 
        return FAILURE;
    if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS )
        return FAILURE;
    if ( typeHeader.t.complexType != TY_BITFIELD ) 
        return FAILURE;
    switch( type ) {
    case SEG_CODE : 
        {   
    		int nBank;
    		SymConvertToBank( addr , nBank );
        	start.addrType = end.addrType = MEM_P0+nBank;
        }
        //start.addrType = end.addrType = 2;
        break;
    case SEG_DATA :
        start.addrType = end.addrType = MEM_I;//4;
        break;
    case SEG_XDATA :                   
        {   
    		int nBank;
    		SymConvertToBank( addr , nBank );
        	start.addrType = end.addrType = MEM_X0+nBank;
        }
        //start.addrType = end.addrType = 3;
        break;
    case SEG_BIT :
        start.addrType = end.addrType = 6;
        break;
    case SEG_REGISTER :
        start.addrType = end.addrType = 5;
        break;
    case SEG_SFR :
        start.addrType = end.addrType = 7;
        break;
    default :
        start.addrType = end.addrType = 0;
        break;
    }   
    start.addr = addr ;
    if ( GOOD != SymGetTypeBitfield(typeIndex,&bit) )
        return FAILURE;
        
    switch ( bit.baseTypeIndex ) {
    case BI_S8_SCHAR:
    case BI_U8_UCHAR:
    case BI_S8_CHAR:  
        if ( (bit.offset+bit.size)>8 ) return FAILURE;
        end.addr = start.addr ;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
#endif  
        ui = data[0];
//      for( i=0;i < bit.offset;i++)
//          ui = ui>>1;
        ui = ui >> bit.offset ;
        uj = 1;
        for(i=0;(U16)i<bit.size;i++)
            uj = uj << 1;
        uj--;
        ui = ui & uj;
        if( bit.baseTypeIndex == BI_U8_UCHAR ) {            
//            if ( (ui>=0x20)&&(ui<=0x7F) )        
//                sprintf(str,"'%c'",(unsigned char)ui);
//                sprintf(str,"'%c' (0x%x)",(unsigned char)ui,ui);
//            else    
//                sprintf(str,"%u",ui);
//                sprintf(str,"%u (0x%x)",ui,ui);
            if ( (ui>=0x20)&&(ui<=0x7F) )        
//                sprintf(str,"'%c'",(unsigned char)ui);
                sprintf(str,"'%c' ",(unsigned char)ui);
//                sprintf(str,"'%c' (0x%x)",(unsigned char)ui,ui);
            else    
//                sprintf(str,"%u",ui);
                sprintf(str,"%u ",ui);
//                sprintf(str,"%u (0x%x)",ui,ui);
            VarU8ToStr((unsigned char)ui,&str[strlen(str)] );
        }
        else {
            uj++;
            if ( ui >= uj/2 )
                i = (int)(ui-uj);
            else 
                i = (int)ui;
//            if( (i>=0x20)&&(i<=0x7F) )
//                sprintf(str,"'%c'",(char)i);
//                sprintf(str,"'%c' (0x%x)",(char)i ,ui);
//            else
//                sprintf(str,"%d",i);
//                sprintf(str,"%d (0x%x)",i ,ui);
            if( (i>=0x20)&&(i<=0x7F) )
//                sprintf(str,"'%c'",(char)i);
                sprintf(str,"'%c' ",(char)i);
//                sprintf(str,"'%c' (0x%x)",(char)i ,ui);
            else
//                sprintf(str,"%d",i);
                sprintf(str,"%d ",i);
//                sprintf(str,"%d (0x%x)",i ,ui);
            VarU8ToStr((unsigned char)ui,&str[strlen(str)] );
        }
        return GOOD;
    case BI_S16_SINT:
    case BI_U16_UINT:
    case BI_S16_SHORT:
    case BI_S16_USHORT:
    case BI_S16_SHORTINT:
    case BI_S16_SSHORT:

    case BI_STACK_INT:
    case BI_STACK_U:
    case BI_STACK_UINT:

        if ( (bit.offset+bit.size)>16 ) return FAILURE;
        end.addr = start.addr+1;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
#endif  
        //ui = (U16) data[0];
        //ui = (ui<<8) + (U8)data[1];
        ui=*((U16*)data);
        
        ui = ui >> bit.offset ;
        uj = 1;
        for(i=0;(U16)i<bit.size;i++)
            uj = uj << 1;
        uj--;
        ui = ui & uj;

        if ( bit.baseTypeIndex==BI_U16_UINT || 
//            bit.baseTypeIndex==BI_S16_USHORT ) {
            bit.baseTypeIndex==BI_S16_USHORT ||
            bit.baseTypeIndex== BI_STACK_U ||
            bit.baseTypeIndex== BI_STACK_UINT ) {
//            sprintf(str,"%u",ui);
            sprintf(str,"%u ",ui);
//            sprintf(str,"%u (0x%x)",ui,ui);
            VarU16ToStr(ui,&str[strlen(str)] );
        }
        else {                 
            uj++;
            if ( ui >= uj/2 )
                i = (int)(ui-uj);
            else
                i = (int)ui;
//            sprintf(str,"%d",(int)i);
            sprintf(str,"%d ",(int)i);
//            sprintf(str,"%d (0x%x)",(int)i,ui);
            VarU16ToStr(ui,&str[strlen(str)] );
        }
        return GOOD;
    default : // U16 ;
        if ( (bit.offset+bit.size)>16 ) return FAILURE;
        end.addr = start.addr+1;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
#endif  
        //ui = (U16) data[0];
        //ui = (ui<<8) + (U8)data[1];
        ui=*((U16*)data);
        ui = ui >> bit.offset ;
        uj = 1;
        for(i=0;(U16)i<bit.size;i++)
            uj = uj << 1;
        uj--;
        ui = ui & uj;

//        sprintf(str,"%u",ui);
        sprintf(str,"%u ",ui);
//        sprintf(str,"%u (0x%x)",ui);
        VarU16ToStr(ui,&str[strlen(str)] );
        return GOOD;
    }
    return GOOD;        
}


/*------------------------------------------------------------------------
** BuildIEEEBValue
**
** Purpose:
**    Build bitfield type value to String for variable server
*/
/*------------------------------------------------------------------------*/
int BuildIEEEBValue(struct VarNode *node, int nFlag, 
    char* str )
{                                                              
    TYPE_HEADER_TYPE typeHeader;
    TYPE_BITFIELD_STRUCT bit;          
    TYPE_INDEX typeIndex;
    struct VarNode *father;
    U32 addr;
    ADDR start , end;
    char data[16] ;
    char temp[256];
    U16 ui , uj;
    int i;            
    RET_ADDR retAddr;
    
    if ( node == 0 ) return FAILURE;
    if ( SrcIsIEEE() != GOOD ) return FAILURE;
    typeHeader.typeName = temp;  
    typeIndex = node->typeIndex;
    if (GOOD != SymGetTypeHeader(typeIndex, &typeHeader)) 
        return FAILURE;
    if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS )
        return FAILURE;
    if ( typeHeader.t.complexType == TY_TYPE ) {
        while( 1 ) {
            TYPE_INDEX       typeNext;
            if ( GOOD != SymGetTypeTypeIndex(typeIndex,&typeNext) ) {
                return FAILURE;
            }
            typeIndex = typeNext;
            if (GOOD != SymGetTypeHeader(typeIndex, &typeHeader)){
                return FAILURE;
            }
            if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS )
                break;
            else if ( typeHeader.t.complexType != TY_TYPE )
                break;
        }   
        if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS ) {
            return FAILURE;
        }
    }

    if ( typeHeader.t.complexType != TY_BITFIELD ) 
        return FAILURE;          
    if ( GOOD != SymGetTypeBitfield(node->typeIndex,&bit) )
        return FAILURE;

    addr = node->addr.addr;
    if ( node->father ) {
        father = node->father;
        if (GOOD != SymGetTypeHeader(father->typeIndex, &typeHeader)) 
            return FAILURE;
        if ( typeHeader.t.complexType == TY_STRUCT ) {
            TYPE_S_U_STRUCT  s;
            ui = 0 ;
            struct VarNode *tt;
            tt = father->son;
            while( tt ) {
                if ( tt == node ) break;
                ui++;          
                tt = tt->next;
            }
            if ( tt == 0 ) return FAILURE;
            s.name = temp ;
            if ( GOOD != SymGetTypeStructUnionNth( father->typeIndex,
                ui , &s ) ) return FAILURE;             
            uj = s.offset >> 3;
            addr = father->result.addr + uj;
            bit.offset += (U8) (s.offset%8); 
        }
    }
    
    switch( node->addr.segType ) {
    case SEG_CODE :
        {   
    		int nBank;
    		SymConvertToBank( addr , nBank );
        	start.addrType = end.addrType = MEM_P0+ nBank;
        }
        //start.addrType = end.addrType = 2;
        break;
    case SEG_DATA :
        start.addrType = end.addrType = MEM_I;//4;
        break;
    case SEG_XDATA :    
       	{   
    		int nBank;
    		SymConvertToBank( addr , nBank );
        	start.addrType = end.addrType =MEM_X0+nBank;
        }
        //start.addrType = end.addrType = 3;
        break;
    case SEG_BIT :
        start.addrType = end.addrType = 6;
        break;
    case SEG_REGISTER :
        start.addrType = end.addrType = 5;
        break;
    case SEG_SFR :
        start.addrType = end.addrType = 7;
        break;
    default :
        start.addrType = end.addrType = 0;
        break;
    }   
    start.addr = addr ;
//  if ( GOOD != SymGetTypeBitfield(typeIndex,&bit) )
//      return FAILURE;
        
    switch ( bit.baseTypeIndex ) {
    case BI_S8_SCHAR:
    case BI_U8_UCHAR:
    case BI_S8_CHAR:  
        if ( (bit.offset+bit.size)>8 ) return FAILURE;
        end.addr = start.addr ;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
#endif  
        ui = data[0];
        ui = ui >> bit.offset ;
        uj = 1;
        for(i=0;(U16)i<bit.size;i++)
            uj = uj << 1;
        uj--;
        ui = ui & uj;
        if( bit.baseTypeIndex == BI_U8_UCHAR ) {     
            if ( nFlag ) {       
                if ( (ui>=0x20)&&(ui<=0x7F) )        
                    sprintf(str,"'%c' ",(unsigned char)ui);
                else    
                    sprintf(str,"%u ",ui);
                VarU8ToStr((unsigned char)ui,&str[strlen(str)] );
            }
            else {
                if ( (ui>=0x20)&&(ui<=0x7F) )        
                    sprintf(str,"'%c',",(unsigned char)ui);
                else    
                    sprintf(str,"%u,",ui);
            }            
        }
        else {
            uj++;
            if ( uj > 2 ) {
                if ( ui >= uj/2 )
                    i = (int)(ui-uj);
                else 
                    i = (int)ui;
            }           
            else i = (int) ui;
            if ( nFlag ) {    
                if( (i>=0x20)&&(i<=0x7F) )
                    sprintf(str,"'%c' ",(char)i);
                else
                    sprintf(str,"%d ",i);
                VarU8ToStr((unsigned char)ui,&str[strlen(str)] );
            }
            else {
                if( (i>=0x20)&&(i<=0x7F) )
                    sprintf(str,"'%c',",(char)i);
                else
                    sprintf(str,"%d,",i);
            }
        }
        return GOOD;
    case BI_S16_SINT:
    case BI_U16_UINT:
    case BI_S16_SHORT:
    case BI_S16_USHORT:
    case BI_S16_SHORTINT:
    case BI_S16_SSHORT:

    case BI_STACK_INT:
    case BI_STACK_U:
    case BI_STACK_UINT:

        if ( (bit.offset+bit.size)>16 ) return FAILURE;
        end.addr = start.addr+1;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr)) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
#endif  

//        ui = (U16) data[0];
//        ui = (ui<<8) + (U8)data[1];
        //ui = (U16) data[1];
        //ui = (ui<<8) + (U8)data[0];
        ui = *( (U16*)data);
        
        ui = ui >> bit.offset ;
        uj = 1;
        for(i=0;(U16)i<bit.size;i++)
            uj = uj << 1;
        uj--;
        ui = ui & uj;

        if ( bit.baseTypeIndex==BI_U16_UINT || 
            bit.baseTypeIndex==BI_S16_USHORT ||
            bit.baseTypeIndex== BI_STACK_U ||
            bit.baseTypeIndex== BI_STACK_UINT ) {
            if ( nFlag ) {
                sprintf(str,"%u ",ui);
                VarU16ToStr(ui,&str[strlen(str)] );
            }
            else {
                sprintf(str,"%u,",ui);
            }
        }
        else {                 
            uj++;             
            if ( uj > 2 ) {
                if ( ui >= uj/2 )
                    i = (int)(ui-uj);
                else
                    i = (int)ui;    
            }    
            else i = (int)ui;    
            if ( nFlag ) {    
                sprintf(str,"%d ",(int)i);
                VarU16ToStr(ui,&str[strlen(str)] );
            }
            else {
                sprintf(str,"%d,",(int)i);
            }
        }
        return GOOD;
    default : // U16 ;
        if ( (bit.offset+bit.size)>16 ) return FAILURE;
        end.addr = start.addr+1;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
#endif  
//        ui = (U16) data[0];
//        ui = (ui<<8) + (U8)data[1];
        //ui = (U16) data[1];
        //ui = (ui<<8) + (U8)data[0];
        ui= *((U16*)data);
        
        ui = ui >> bit.offset ;
        uj = 1;
        for(i=0;(U16)i<bit.size;i++)
            uj = uj << 1;
        uj--;
        ui = ui & uj;

        if ( nFlag ) {
            sprintf(str,"%u ",ui);
            VarU16ToStr(ui,&str[strlen(str)] );
        }
        else {
            sprintf(str,"%u,",ui);
        }
        return GOOD;
    }
    return GOOD;        
}

/*------------------------------------------------------------------------
** BuildCValue
**
** Purpose:
**    Build complex types value to String for variable server
*/
/*------------------------------------------------------------------------*/
int BuildCAddr( SEGMENTTYPE type , U32 addr , char* str )
{
    int nBank;
    switch( type ) {
    case SEG_CODE :             
    	nBank =(int)(addr >>16);
        sprintf( str , "P%d:", nBank);
        break;
    case SEG_DATA :
        CPUMEMORYRANGE cmr;
        GetMemoryRange(cmr);
        if(cmr.iMax < addr) sprintf( str , "X0:" );  
        else sprintf( str , "I:" );  
        break;
    case SEG_XDATA :
    	nBank =(int)(addr >>16);
        sprintf( str , "X%d:", nBank);
        break;
    case SEG_BIT :
        sprintf( str , "B:" );
        break;
    case SEG_REGISTER :
        sprintf( str , "R:" );
        break;        
    case SEG_SFR :
    	sprintf( str , "S:" );
    	break;
    default :
        sprintf( str , "U:" );
        break;
    }
    U16ToStr( (U16)addr , &str[strlen(str)] );
    //22str[] = '\0';
    return GOOD;    
}

/*------------------------------------------------------------------------
** DisplayStack
**
** Purpose:
**    Display stack information to shell window
*/
/*------------------------------------------------------------------------*/
void DisplayStack()
{
    class stkServer stk;
    
    stk.buildStack();
    stk.DisplayToShell();
    stk.deleteAll();
}

/*------------------------------------------------------------------------
** ConvertToFunc
**
** Purpose:
**    Convert block descriptor to function descriptor
*/
/*------------------------------------------------------------------------*/
int ConvertToFunc(SYM_DESCRIPTOR desc , SYM_DESCRIPTOR& nextDesc)
{
    COMMON_SYMBOL_HEADER  *modPtr , *funcPtr;

    nextDesc = desc;
    modPtr = 0;
    funcPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(desc);
    if ( ((funcPtr->typeIndex.symType)&0x0F) == SYM_FUNCTION ) {
        while ( funcPtr->symParentOffset != NULL_SYMBOL ) {
            if (!UtilIsValidSymDescriptor( funcPtr->symParentOffset )) {
                return FAILURE;
            }
            if ( modPtr )
                nextDesc = modPtr->symParentOffset;
            modPtr = funcPtr ;
            funcPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(
                funcPtr->symParentOffset);
            if ( ((funcPtr->typeIndex.symType)&0x0F) == SYM_MODULE )
                break;
        }
    }
    else {
        return FAILURE;
    }
    return GOOD;
}

/*------------------------------------------------------------------------
** LstAddr2Info
**
** Purpose:
**    Convert a address to module and function information
*/
/*------------------------------------------------------------------------*/
int LstAddr2Info(U32 addr,U32& moduleDesc,U32& modStart,U32& modEnd,
                          U32& funcDesc, U32& funcStart,U32& funcEnd)
{
    ADDRESS_TYPE     address;
    RETCODE          err = GOOD;
    MEM_ADDR_CLASS   memoryClass;
    SYM_TYPE_TYPE    symbolType;

    COMMON_SYMBOL_HEADER  *modPtr ;
//    ADDR_RANGE_TYPE  addrRange;
    SYM_DESCRIPTOR ModuleDesc;
    SYM_DESCRIPTOR FunctionDesc;
    SYM_DESCRIPTOR LowestLevelDesc;
    U32 SymbolOffset;  /* distance from currentPC to found symbol */

    if ( SrcIsLoaded() != GOOD ) return FAILURE;

    address.addr = addr;
    address.segType = SEG_CODE;
    err = SymMapAddr2Symbol(address,
                &memoryClass,
                &symbolType,
                &SymbolOffset,
                &LowestLevelDesc,
                &FunctionDesc,
                &ModuleDesc);
    if (GOOD == err) {
        if ( FunctionDesc != NULL_SYMBOL ) {
            if ( GOOD != ConvertToFunc(FunctionDesc , LowestLevelDesc) )
                return FAILURE;
            moduleDesc = ModuleDesc ;
            funcDesc = LowestLevelDesc ;
        }
        else if (ModuleDesc != NULL_SYMBOL) {
            moduleDesc = ModuleDesc ;
            funcDesc = NULL_SYMBOL;
        }
        else {
            return FAILURE;
        }
        if (!UtilIsValidSymDescriptor( moduleDesc )) {
            return FAILURE;
        }
        modPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(moduleDesc);
        modStart = modPtr->beginAddrInfo.startAddr ;
        modEnd = modPtr->endAddrInfo.endAddr ;
        if ( funcDesc != NULL_SYMBOL ) {
            if (!UtilIsValidSymDescriptor( funcDesc )) {
                return FAILURE;
            }
            modPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(funcDesc);
            funcStart = modPtr->beginAddrInfo.startAddr ;
            funcEnd = modPtr->endAddrInfo.endAddr ;
        }             
        return GOOD;
    }
    else return FAILURE;
}

/*------------------------------------------------------------------------
** GetLibRange
**
** Purpose:
**    Convert a address to module and function information
*/
/*------------------------------------------------------------------------*/
int GetLibRange(U32 uAddr,U32& uStart,U32& uEnd)
{                
    U32 modStart, modEnd;
    ADDRESS_TYPE     address;
    RETCODE          err = GOOD;
    MEM_ADDR_CLASS   memoryClass;
    SYM_TYPE_TYPE    symbolType;

    COMMON_SYMBOL_HEADER  *modPtr ;
    SYM_DESCRIPTOR ModuleDesc;
    SYM_DESCRIPTOR FunctionDesc;
    SYM_DESCRIPTOR LowestLevelDesc;
    SYM_DESCRIPTOR desc;
    U32 SymbolOffset;  /* distance from currentPC to found symbol */

    if ( SrcIsLoaded() != GOOD ) return FAILURE;

    address.addr = uAddr;
    address.segType = SEG_CODE;
    err = SymMapAddr2Symbol(address,
                &memoryClass,
                &symbolType,
                &SymbolOffset,
                &LowestLevelDesc,
                &FunctionDesc,
                &ModuleDesc);
    if (GOOD == err) {
        if ( FunctionDesc != NULL_SYMBOL ) {
            desc = FunctionDesc;            
        }
        else if (ModuleDesc != NULL_SYMBOL) {
            desc = ModuleDesc;
        }
        else {
            return FAILURE;
        }
        if (!UtilIsValidSymDescriptor( desc )) {
            return FAILURE;
        }
        modPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(desc);
        modStart = modPtr->beginAddrInfo.startAddr ;
        modEnd = modPtr->endAddrInfo.endAddr ;
        uStart = modStart;
        uEnd = modEnd;
        if ( (uAddr > uEnd)||(uAddr < uStart) ) return FAILURE;
        return GOOD;
    }
    else return FAILURE;
}

/*------------------------------------------------------------------------
** LstGetSymbolName
**
** Purpose:
**    get symbol name by symbol descriptor
*/
/*------------------------------------------------------------------------*/
int LstGetSymbolName(LPSTR name,U32 desc)
{ 
    HANDLE *pHdl;
    char *temp1;

    if ( GOOD != SymGetSymbolName( desc , &temp1 ) )
        return FAILURE;
    sprintf( name , "#%s", temp1 );
    if ( temp1 ) {
        pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
        GlobalFree( *pHdl );
    }
    temp1 = 0;
    return GOOD;
}  

/*------------------------------------------------------------------------
** StkGetStkLevelNum
**
** Purpose:
**    build stack information and get stack level number
*/
/*------------------------------------------------------------------------*/
extern "C" int WINAPI StkGetStkLevelNum( int& num )
{                              
//    if ( GOOD != stkObject.buildStack() ) return FAILURE;
    stkObject.buildStack();
    stkObject.GetNumber( num );
    return GOOD;
}

/*------------------------------------------------------------------------
** StkLevelToNode
**
** Purpose:
**    convert stack level information to stack node
*/
/*------------------------------------------------------------------------*/
extern "C" int WINAPI StkLevelToNode(int nLevel , struct STKNode* &node)
{
    node = stkObject.GetHeader();
    if ( node == NULL ) return FAILURE;
    if ( nLevel < 0 ) return FAILURE;
    while( node ) {
        if ( nLevel == 0 ) break;
        nLevel --;
        node = node->next ;
    }
    if ( node == 0 ) return FAILURE;
    return GOOD;
}
    
/*------------------------------------------------------------------------
** StkGetStkFirstNode
**
** Purpose:
**    get stack information link first node
*/
/*------------------------------------------------------------------------*/
extern "C" int WINAPI StkGetStkFirstNode( STKNode* & node )
{
//    if ( GOOD != stkObject.buildStack() ) return FAILURE;
    stkObject.buildStack();
    node = stkObject.GetHeader();
    if ( node == NULL ) return FAILURE;
    return GOOD;
}

/*------------------------------------------------------------------------
** StkGetStkNextNode
**
** Purpose:
**    get one node in stack information link next node
*/
/*------------------------------------------------------------------------*/
extern "C" int WINAPI StkGetStkNextNode( STKNode* & node , STKNode* & nextNode )
{
    if ( node == NULL ) return FAILURE;
    nextNode = node->next;
    if ( nextNode == NULL ) return FAILURE;
    return GOOD;
}

/*------------------------------------------------------------------------
** StkGetStkPrevNode
**
** Purpose:
**    get one node in stack information link prev node
*/
/*------------------------------------------------------------------------*/
int StkGetStkPrevNode( STKNode*& node , STKNode* & prevNode )
{
    if ( node == NULL ) return FAILURE;
    prevNode = node->prev;
    if ( prevNode == NULL ) return FAILURE;
    return GOOD;
}
             
/*------------------------------------------------------------------------
** StkGetNodeDisplayString
**
** Purpose:
**    generate stack link one node's information to five CString
*/
/*------------------------------------------------------------------------*/
/****************************************************************
*  Modify by Gates Hua , 9/7/95 for bug 0045
*****************************************************************/
extern "C"int WINAPI StkGetNodeDisplayString(STKNode* node,CString& s1,CString& s2,
                            CString& s3,CString& s4,CString& s5 )
{
    char temp[1024];
    int i;
    COMMON_SYMBOL_HEADER  *modPtr , *funcPtr;
    HANDLE *pHdl;
    char *temp1;
    SYM_DESCRIPTOR nextDesc;

    if ( node == NULL ) return FAILURE;
    temp1 = 0;
    i = 0;
//    sprintf( temp , "%x" , node->num );
    sprintf( temp , "%d" , node->num );
    s1 = temp; // num
    sprintf( temp , "%lx" , node->addr );    
    s2 = temp; // addr

    if ( node->next ) {
        if ( node->next->flag == 1 ) {
            if ( GOOD == SymGetSymbolName(node->next->desc,&temp1) ) {
                modPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(
                            node->next->desc);
                sprintf( temp,"%s+%lx ",temp1,( node->next->addr -
                         modPtr->beginAddrInfo.startAddr ) );
                s3 = temp;
                if ( temp1 ) {
                    pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
                    GlobalFree( *pHdl );
                }
                temp1 = 0;  
            }
            else s3 = "";
        }
        else {
            nextDesc = node->next->desc;
            modPtr = 0;
            funcPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(nextDesc);
            if ( ((funcPtr->typeIndex.symType)&0x0F) == SYM_FUNCTION ) {
                while ( funcPtr->symParentOffset != NULL_SYMBOL ) {
                    if (!UtilIsValidSymDescriptor( funcPtr->symParentOffset )) {
                        nextDesc = NULL_SYMBOL ;
                        break;
                    }
                    if ( modPtr )
                        nextDesc = modPtr->symParentOffset;
                    modPtr = funcPtr ;
                    funcPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(
                           funcPtr->symParentOffset);
                    if ( ((funcPtr->typeIndex.symType)&0x0F) == SYM_MODULE )
                        break;
                }               
                if ( GOOD == SymGetSymbolName( nextDesc , &temp1 ) ) {
                    if ( modPtr == 0 ) modPtr = funcPtr ;
                    sprintf(temp,"%s+%lx ",temp1,( node->next->addr -
                            modPtr->beginAddrInfo.startAddr ) );
                    s3 = temp;        
                    if ( temp1 ) {
                        pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
                        GlobalFree( *pHdl );
                    }
                    temp1 = 0;
                }
                else s3 = "";
            }                   
            else s3 = "";
        }
    }                   
    else s3 = "";
    if ( node->flag == 1 ) {
        if ( GOOD != SymGetSymbolName( node->desc , &temp1 ) )
            return FAILURE;
        modPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(node->desc);
//        sprintf( temp , "%s+%x" ,temp1 , (int)( node->addr -
//                 (U16) modPtr->beginAddrInfo.startAddr ) );
//        s3 = temp;
        sprintf( temp , "%s" , temp1 );
        s4 = temp;
        if ( temp1 ) {
            pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
            GlobalFree( *pHdl );
        }
        temp1 = 0;  
        s5 = "";
    }
    else {
        nextDesc = node->desc;
        modPtr = 0;
        funcPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(node->desc);
        if ( ((funcPtr->typeIndex.symType)&0x0F) == SYM_FUNCTION ) {
            while ( funcPtr->symParentOffset != NULL_SYMBOL ) {
                if (!UtilIsValidSymDescriptor( funcPtr->symParentOffset )) {
                    return FAILURE;
                }
                if ( modPtr )
                    nextDesc = modPtr->symParentOffset;
                modPtr = funcPtr ;
                funcPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(
                       funcPtr->symParentOffset);
                if ( ((funcPtr->typeIndex.symType)&0x0F) == SYM_MODULE )
                    break;
            }
//            if ( GOOD != SymGetSymbolName( nextDesc , &temp1 ) )
//                return FAILURE;
            if ( modPtr == 0 ) modPtr = funcPtr ;
//            sprintf( temp , "%s+%x " ,temp1 , (int)( node->addr -
//                    (U16) modPtr->beginAddrInfo.startAddr ) );
//            s3 = temp;        
//            if ( temp1 ) {
//                pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
//                GlobalFree( *pHdl );
//            }
//            temp1 = 0;
            if ( GOOD != SymGetSymbolName( modPtr->symParentOffset , &temp1 ) )
                return FAILURE;      
            sprintf( temp , "%s" , temp1 );
            s4 = temp;   
            if ( temp1 ) {
                pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
                GlobalFree( *pHdl );
            }
            temp1 = 0;
            if ( GOOD != DisplayParameters(node->addr,nextDesc,temp) )
                return FAILURE;                            
            s5 = temp;      
        }                   
        else return FAILURE;
    }
    return GOOD;
}

/*------------------------------------------------------------------------
** ConvEnumToAbiType
**
** Purpose:
**    corvert symbol server segment enum value to abi segment value
*/
/*------------------------------------------------------------------------*/
void ConvEnumToAbiType( SEGMENTTYPE type , U16& addrType )
{
    switch( type ) {
    case SEG_CODE :   
        addrType = MEM_P0;
        break;
    case SEG_DATA :
        addrType = MEM_I;
        break;
    case SEG_XDATA :
        addrType = MEM_X0;
        break;
    case SEG_BIT :
        addrType = 6;
        break;
    case SEG_REGISTER :
        addrType = 5;
        break;
    case SEG_SFR :
        addrType = 7;
        break;
    default :
        addrType = 0;
        break;
    }   
}

/*------------------------------------------------------------------------
** Omf51ConvPtrToSeg
**
** Purpose:
**    corvert char to symbol server segment enum value for omf51 loader
*/
/*------------------------------------------------------------------------*/
void Omf51ConvPtrToSeg( char c , SEGMENTTYPE& type )
{
    switch( c ) {
    case 1 :
    case 4 :
        type = SEG_DATA ;
        break;
    case 2 :
    case 3 :
        type = SEG_XDATA ;
        break;
    case 5 :
        type = SEG_CODE;
        break;
    default :
        type = SEG_UNTYPED;
        break;
    }
}

/*------------------------------------------------------------------------
** UbrofConvPtrToSeg
**
** Purpose:
**    corvert char to symbol server segment enum value for ubrof loader
*/
/*------------------------------------------------------------------------*/
void UbrofConvPtrToSeg( char c , SEGMENTTYPE& type )
{
    switch( c ) {
    case 0 :
        type = SEG_DATA ;
        break;
    case 1 :
    case 3 :
        type = SEG_XDATA ;
        break;
    case 2 :
        type = SEG_CODE;
        break;
    default :
        type = SEG_UNTYPED;
        break;
    }
}

/*------------------------------------------------------------------------
** MemoryTypeConvToSeg
**
** Purpose:
**    corvert memory type value to symbol server segment enum value
*/
/*------------------------------------------------------------------------*/
void MemoryTypeConvToSeg( MEMORY_TYPE t , SEGMENTTYPE& type )
{
    switch ( t ) {
    case PDATA_51 :
    case DATA_51 :
    case IDATA_51 :
        type = SEG_DATA;
        break;
    case XDATA_51 :
        type = SEG_XDATA;
        break;
    case CODE_51 :
        type = SEG_CODE;
        break;
    default :
        type = SEG_UNTYPED;
        break;
    }
}

/*------------------------------------------------------------------------
** stkServer::IsValidVar
**
** Purpose:
**    corvert string to valid symbol .
*/
/*------------------------------------------------------------------------*/
/*
int stkServer::IsValidVar(char *command,BOOLEAN& isGlobal,SYM_DESCRIPTOR& symDesc)
{
    struct STKNode *node;
    
    BOOLEAN globalFlag;
    SYM_DESCRIPTOR tempDesc , moduleDesc , funcDesc ;
    
    char *strName[3];
    
    char temp[1024];
    int i , j , k;
    COMMON_SYMBOL_HEADER  *modPtr , *funcPtr;
    HANDLE *pHdl;
    char *temp1;
    SYM_DESCRIPTOR nextDesc;
//    ADDRESS_TYPE     address;
    RETCODE          err = GOOD;
//    MEM_ADDR_CLASS   memoryClass;
    SYM_TYPE_TYPE    symType;

    if ( SrcIsLoaded() != GOOD ) return FAILURE;
                     
    symType = SYM_UNDEFINED;                     
    moduleDesc = funcDesc = NULL_SYMBOL;

//    strcpy( temp , command );
    if ( *command != '#' ) {
    	temp[0] = '#';
	    strcpy( &temp[1] , command );
    }
    else
	    strcpy( temp , command );
                    
    globalFlag = TRUE;                  
    isGlobal = TRUE;
    symDesc = NULL_SYMBOL;
    
    if ( temp[0] != '#' ) return FAILURE;
    
    i = 0;
    j = 0;
    while ( temp[j] != '\0' ) {
        if ( temp[j] == '#' ) {
            k = j+1;
            while( (temp[k] != '\0')&&(temp[k] != '#') ) k++;
            if ( (i==2)&&(temp[k] == '#') ) {
                delete strName[0];
                delete strName[1];
//                delete strName[2];
                return FAILURE;
            }
            strName[i] = new char[ k - j + 1];
            memset( strName[i] , 0 , (k-j+1) );
            if ( strName[i] == 0 ) return FAILURE;
            strncpy(strName[i] , &temp[j+1] , k-j-1 );
            i++; 
            j = k;
        }
        else j++;   
    }

    switch ( i ) {
    case 1 :
        break;
    case 2 :
        symType = SYM_UNDEFINED;                     
        err = SymGetModuleDesc( strName[0],"",&tempDesc);
        if ( GOOD == err) {
            moduleDesc = tempDesc ;
        }                  
        else {
            err = SymGetSymbolFromContext(NULL_SYMBOL,
                                          strName[0],
                                          &symType,
                                          &tempDesc,
                                          &globalFlag);
            if ((GOOD == err) && (SYM_FUNCTION == symType)) {
                funcDesc = tempDesc ;
            }
            else return FAILURE;
        }
        break;
    case 3 :
//      symType = SYM_UNDEFINED;                     
        err = SymGetModuleDesc( strName[0],"",&tempDesc);
//        err = SymGetSymbolFromContext(NULL_SYMBOL,
//                                     strName[0],
//                                      &symType,
//                                      &tempDesc,
//                                      &globalFlag);
        if (GOOD == err) {
            moduleDesc = tempDesc ;
        }
        else return FAILURE;
        symType = SYM_UNDEFINED;                     
        err = SymGetSymbolFromContext(NULL_SYMBOL,
                                      strName[1],
                                      &symType,
                                      &tempDesc,
                                      &globalFlag);
        if ((GOOD == err) && (SYM_FUNCTION == symType)) {
            funcDesc = tempDesc ;
        }
        else return FAILURE;
        break;
    default :
        return FAILURE;
    }
    
    i--;
            
    
    node = stkListHeader ;
    while ( node ) {
        if ( node->flag == 0 ) {
            nextDesc = node->desc;
            modPtr = 0;
            funcPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(node->desc);
            if ( ((funcPtr->typeIndex.symType)&0x0F) == SYM_FUNCTION ) {
                while ( funcPtr->symParentOffset != NULL_SYMBOL ) {
                    if (!UtilIsValidSymDescriptor( funcPtr->symParentOffset )) {
                        return FAILURE;
                    }
                    nextDesc = funcPtr->symParentOffset;
                    funcPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(
                           funcPtr->symParentOffset);
                    if ( ((funcPtr->typeIndex.symType)&0x0F) == SYM_MODULE )
                        break;
                }                      
                
                err = GOOD;
                if ( moduleDesc != NULL ) 
                    if ( moduleDesc != nextDesc ) err = FAILURE;
               
                if ( funcDesc != NULL ) 
                    if ( funcDesc != node->desc ) err = FAILURE;

                if ( err == GOOD ) {              
                    if ( node->desc1 != NULL_SYMBOL ) 
                        nextDesc = node->desc1;
                    else 
                        nextDesc = node->desc;
                    symType = SYM_UNDEFINED;                     
                    if ( GOOD == SymGetSymbolFromContext(nextDesc,
                                                  strName[i],
                                                  &symType,
                                                  &tempDesc,
                                                  &globalFlag) ) {
                        if ( (symType == SYM_GLOBAL_VAR)||
                             (symType == SYM_LOCAL_VAR)||
                             (symType == SYM_USER_DEFINED_VAR) ||
                             (symType == SYM_PUBLIC_VAR) ) {
                             if ( globalFlag == FALSE ) break;
                        }
                    }
                }
            }
        }
        else {          
            nextDesc = node->desc;
            if ( moduleDesc != NULL ) 
                if ( moduleDesc != nextDesc ) err = FAILURE;
               
            symType = SYM_UNDEFINED;                     
            if ( GOOD == SymGetSymbolFromContext(nextDesc,
                                          strName[i],
                                          &symType,
                                          &tempDesc,
                                          &globalFlag) ) {
                if ( (symType == SYM_GLOBAL_VAR)||
                     (symType == SYM_LOCAL_VAR)||
                     (symType == SYM_USER_DEFINED_VAR) ||
                     (symType == SYM_PUBLIC_VAR) ) {
                     if ( globalFlag == FALSE ) break;
                }
            }
        }
        globalFlag = TRUE;
        node = node->next;
    }                   
    err = GOOD;
    if ( globalFlag == FALSE ) {
        symDesc = tempDesc;       
        if ( symType == SYM_GLOBAL_VAR )
            isGlobal = TRUE ;
        else 
            isGlobal = globalFlag;
    }
    else {
        symType = SYM_UNDEFINED;                     
        if ( GOOD == SymGetSymbolFromContext(NULL_SYMBOL,
                                            strName[i],
                                            &symType,
                                            &tempDesc,
                                            &globalFlag) ) {
            if ( (symType == SYM_GLOBAL_VAR)||
                 (symType == SYM_LOCAL_VAR)||
                 (symType == SYM_USER_DEFINED_VAR) ||
                 (symType == SYM_PUBLIC_VAR) ) {
                 symDesc = tempDesc;
                 if ( symType == SYM_GLOBAL_VAR )
                    isGlobal = TRUE;
                 else   
                    isGlobal = globalFlag;
            } 
            else err = FAILURE;
        }                      
        else err = FAILURE;
    }
    
    if ( err == GOOD ) {
        funcPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(symDesc);
        if ( GOOD != SymGetSymbolName( symDesc , &temp1 ) )
            return FAILURE;
        sprintf( temp , "%s %x-%x " ,temp1 , 
            (U16)funcPtr->beginAddrInfo.startAddr,
            (U16)funcPtr->endAddrInfo.endAddr );
        if ( temp1 ) {
            pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
            GlobalFree( *pHdl );
        }
        temp1 = 0;
//        SymShowLine( temp );
    }           

    for( j = 0;j <= i;j++ ) {
        delete strName[j];
    }
//    return GOOD;
    if ( err != GOOD ) return FAILURE;
    return GOOD;
}
*/
int stkServer::IsValidVar(char *command,BOOLEAN& isGlobal,SYM_DESCRIPTOR& symDesc,
	SYM_DESCRIPTOR symSpecModule,int nLine)
{
    struct STKNode *node;
    
    BOOLEAN globalFlag;
    SYM_DESCRIPTOR tempDesc , moduleDesc , funcDesc ;
    
    char *strName[3];
    
    char temp[1024];
    int i , j , k;
    COMMON_SYMBOL_HEADER  *modPtr , *funcPtr;
    HANDLE *pHdl;
    char *temp1;
    SYM_DESCRIPTOR nextDesc;
//    ADDRESS_TYPE     address;
    RETCODE          err = GOOD;
//    MEM_ADDR_CLASS   memoryClass;
    SYM_TYPE_TYPE    symType;
    U32 uAddr;

    if ( SrcIsLoaded() != GOOD ) return FAILURE;
                     
    symType = SYM_UNDEFINED;                     
    moduleDesc = funcDesc = NULL_SYMBOL;

//    strcpy( temp , command );
    if ( *command != '#' ) {
    	temp[0] = '#';
	    strcpy( &temp[1] , command );
    }
    else
	    strcpy( temp , command );
                    
    globalFlag = TRUE;                  
    isGlobal = TRUE;
    symDesc = NULL_SYMBOL;
    
    if ( temp[0] != '#' ) return FAILURE;
    
    i = 0;
    j = 0;
    while ( temp[j] != '\0' ) {
        if ( temp[j] == '#' ) {
            k = j+1;
            while( (temp[k] != '\0')&&(temp[k] != '#') ) k++;
            if ( (i==2)&&(temp[k] == '#') ) {
                delete strName[0];
                delete strName[1];
//                delete strName[2];
                return FAILURE;
            }
            strName[i] = new char[ k - j + 1];
            memset( strName[i] , 0 , (k-j+1) );
            if ( strName[i] == 0 ) return FAILURE;
            strncpy(strName[i] , &temp[j+1] , k-j-1 );
            i++; 
            j = k;
        }
        else j++;   
    }

    switch ( i ) {
    case 1 :
        break;
    case 2 :
        symType = SYM_UNDEFINED;                     
        err = SymGetModuleDesc( strName[0],"",&tempDesc);
        if ( GOOD == err) {
            moduleDesc = tempDesc ;
        }                  
        else {
            err = SymGetSymbolFromContext(NULL_SYMBOL,
                                          strName[0],
                                          &symType,
                                          &tempDesc,
                                          &globalFlag);
            if ((GOOD == err) && (SYM_FUNCTION == symType)) {
                funcDesc = tempDesc ;
            }
            else return FAILURE;
        }
        break;
    case 3 :
//      symType = SYM_UNDEFINED;                     
        err = SymGetModuleDesc( strName[0],"",&tempDesc);
//        err = SymGetSymbolFromContext(NULL_SYMBOL,
//                                     strName[0],
//                                      &symType,
//                                      &tempDesc,
//                                      &globalFlag);
        if (GOOD == err) {
            moduleDesc = tempDesc ;
        }
        else return FAILURE;
        symType = SYM_UNDEFINED;                     
        err = SymGetSymbolFromContext(NULL_SYMBOL,
                                      strName[1],
                                      &symType,
                                      &tempDesc,
                                      &globalFlag);
        if ((GOOD == err) && (SYM_FUNCTION == symType)) {
            funcDesc = tempDesc ;
        }
        else return FAILURE;
        break;
    default :
        return FAILURE;
    }
    
    i--;
            
	if ( symSpecModule != 0 ) {
	    SYM_DESCRIPTOR modDesc;
	    LINENUM_TYPE line;
	    ADDR_RANGE_TYPE addrRange;
	    LINENUM_TYPE    actualLinenum;
	    COLUMN_TYPE     actualColumn;
	    LINENUM_DESCRIPTOR  nextIndex;
	    SYM_DESCRIPTOR ModuleDesc;
	    SYM_DESCRIPTOR FunctionDesc;
	    SYM_DESCRIPTOR LowestLevelDesc;
	    
		if ( moduleDesc ) {
			if ( moduleDesc != symSpecModule ) return FAILURE;
		}
		else moduleDesc = symSpecModule;
	    
	    modDesc = moduleDesc;
	    line = nLine; 
	    if ( GOOD != SymGetLinenum(modDesc,  line,
	        &addrRange, &actualLinenum, &actualColumn, &nextIndex) ) {
	        return FAILURE;
	    }
	    uAddr = addrRange.startAddr;
	    if ( moduleDesc ) {
	        funcPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(moduleDesc);
	        if ( uAddr < funcPtr->beginAddrInfo.startAddr || 
	        	uAddr > funcPtr->endAddrInfo.endAddr )
	        	return FAILURE;
	    }
	    if ( funcDesc ) {
	        funcPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(funcDesc);
	        if ( uAddr < funcPtr->beginAddrInfo.startAddr || 
	        	uAddr > funcPtr->endAddrInfo.endAddr )
	        	return FAILURE;
	    }
        if ( GOOD != (RETCODE) StackAddrMapBlock(uAddr,ModuleDesc,
                    FunctionDesc,LowestLevelDesc) ) return FAILURE;
        if ( FunctionDesc ) {
        	if ( LowestLevelDesc ) nextDesc = LowestLevelDesc;
        	else nextDesc = FunctionDesc;
        }
        else 
        	nextDesc = ModuleDesc;
        if ( GOOD == SymGetSymbolFromContext(nextDesc,
                                      strName[i],
                                      &symType,
                                      &tempDesc,
                                      &globalFlag) ) {
            if ( (symType == SYM_GLOBAL_VAR)||
                 (symType == SYM_LOCAL_VAR)||
                 (symType == SYM_USER_DEFINED_VAR) ||
                 (symType == SYM_PUBLIC_VAR) ) {
            }
            else globalFlag == TRUE;
        }
	    else globalFlag == TRUE;
	}

	if ( symSpecModule == 0 ) {
	    node = stkListHeader ;
	    while ( node ) {
	        if ( node->flag == 0 ) {
	            nextDesc = node->desc;
	            modPtr = 0;
	            funcPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(node->desc);
	            if ( ((funcPtr->typeIndex.symType)&0x0F) == SYM_FUNCTION ) {
	                while ( funcPtr->symParentOffset != NULL_SYMBOL ) {
	                    if (!UtilIsValidSymDescriptor( funcPtr->symParentOffset )) {
	                        return FAILURE;
	                    }
	                    nextDesc = funcPtr->symParentOffset;
	                    funcPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(
	                           funcPtr->symParentOffset);
	                    if ( ((funcPtr->typeIndex.symType)&0x0F) == SYM_MODULE )
	                        break;
	                }                      
	                
	                err = GOOD;
	                if ( moduleDesc != NULL ) 
	                    if ( moduleDesc != nextDesc ) err = FAILURE;
	               
	                if ( funcDesc != NULL ) 
	                    if ( funcDesc != node->desc ) err = FAILURE;
	
	                if ( err == GOOD ) {              
	                    if ( node->desc1 != NULL_SYMBOL ) 
	                        nextDesc = node->desc1;
	                    else 
	                        nextDesc = node->desc;
	                    symType = SYM_UNDEFINED;                     
	                    if ( GOOD == SymGetSymbolFromContext(nextDesc,
	                                                  strName[i],
	                                                  &symType,
	                                                  &tempDesc,
	                                                  &globalFlag) ) {
	                        if ( (symType == SYM_GLOBAL_VAR)||
	                             (symType == SYM_LOCAL_VAR)||
	                             (symType == SYM_USER_DEFINED_VAR) ||
	                             (symType == SYM_PUBLIC_VAR) ) {
	                             if ( globalFlag == FALSE ) break;
	                        }
	                    }
	                }
	            }
	        }
	        else {          
	            nextDesc = node->desc;
	            if ( moduleDesc != NULL ) 
	                if ( moduleDesc != nextDesc ) err = FAILURE;
	               
	            symType = SYM_UNDEFINED;                     
	            if ( GOOD == SymGetSymbolFromContext(nextDesc,
	                                          strName[i],
	                                          &symType,
	                                          &tempDesc,
	                                          &globalFlag) ) {
	                if ( (symType == SYM_GLOBAL_VAR)||
	                     (symType == SYM_LOCAL_VAR)||
	                     (symType == SYM_USER_DEFINED_VAR) ||
	                     (symType == SYM_PUBLIC_VAR) ) {
	                     if ( globalFlag == FALSE ) break;
	                }
	            }
	        }
	        globalFlag = TRUE;
	        node = node->next;
	    }               
	}

    err = GOOD;
    if ( globalFlag == FALSE ) {
        symDesc = tempDesc;       
        if ( symType == SYM_GLOBAL_VAR )
            isGlobal = TRUE ;
        else 
            isGlobal = globalFlag;
    }
    else {
        symType = SYM_UNDEFINED;                     
        if ( GOOD == SymGetSymbolFromContext(NULL_SYMBOL,
                                            strName[i],
                                            &symType,
                                            &tempDesc,
                                            &globalFlag) ) {
            if ( (symType == SYM_GLOBAL_VAR)||
                 (symType == SYM_LOCAL_VAR)||
                 (symType == SYM_USER_DEFINED_VAR) ||
                 (symType == SYM_PUBLIC_VAR) ) {
                 symDesc = tempDesc;
                 if ( symType == SYM_GLOBAL_VAR )
                    isGlobal = TRUE;
                 else   
                    isGlobal = globalFlag;
            } 
            else err = FAILURE;
        }                      
        else err = FAILURE;
    }
    
    if ( err == GOOD ) {
        funcPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(symDesc);
        if ( GOOD != SymGetSymbolName( symDesc , &temp1 ) )
            return FAILURE;
        sprintf( temp , "%s %x-%x " ,temp1 , 
            (U16)funcPtr->beginAddrInfo.startAddr,
            (U16)funcPtr->endAddrInfo.endAddr );
        if ( temp1 ) {
            pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
            GlobalFree( *pHdl );
        }
        temp1 = 0;
//        ShowLine( temp );
    }           

    for( j = 0;j <= i;j++ ) {
        delete strName[j];
    }
//    return GOOD;
    if ( err != GOOD ) return FAILURE;
    return GOOD;
}

/*------------------------------------------------------------------------
** stkServer::InitStkLocalVar
**
** Purpose:
**    stack local variable initial routine .
*/
/*------------------------------------------------------------------------*/
int stkServer::InitStkLocalVar(int nLevel)
{                                                     
    struct STKNode *temp;
    COMMON_SYMBOL_HEADER  *varPtr;
    COMMON_BLOCK_HEADER  *blockPtr;
    int n;
    
    n = nLevel ;
    m_blockDesc = NULL_SYMBOL;
    m_varDesc = NULL_SYMBOL;
    if ( n < 0 ) return FAILURE;
    temp = stkListHeader ;      
    while( temp ) {
        if ( n == 0 ) break;
        n--;
        temp = temp->next;
    }
    if ( temp == 0 ) return FAILURE;
    if ( n != 0 ) return FAILURE;
    if ( temp->num != nLevel ) return FAILURE;
    if ( temp->flag != 0 )  return FAILURE;
    if ( temp->desc1 != 0 ) m_blockDesc = temp->desc1;
    else m_blockDesc = temp->desc;
    
    while ( m_blockDesc != NULL_SYMBOL ) {
        if (!UtilIsValidSymDescriptor(m_blockDesc)) return FAILURE;
        blockPtr=(COMMON_BLOCK_HEADER *)st.GetHugeDataPtr(m_blockDesc);
        if ( ((blockPtr->symHeader.typeIndex.symType)&0x0F) == SYM_MODULE ) 
            return FAILURE;
        if (m_varDesc == NULL_SYMBOL) {
            m_varDesc = blockPtr->list.varListOffset ;
        }
        else {
            if (!UtilIsValidSymDescriptor(m_varDesc)) return FAILURE;
            varPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(m_varDesc);
            m_varDesc = varPtr->symSiblingOffset;
        }
        if ( m_varDesc == NULL_SYMBOL ) {
            m_blockDesc = blockPtr->symHeader.symParentOffset ;
        }
        else break;
    }
    if ( (m_blockDesc==NULL_SYMBOL)||(m_varDesc==NULL_SYMBOL) ) 
        return FAILURE;
    return GOOD; 
}


/*------------------------------------------------------------------------
** stkServer::GetStkLocalVar
**
** Purpose:
**    get stack local variable information .
*/
/*------------------------------------------------------------------------*/
int stkServer::GetStkLocalVar(SYM_DESCRIPTOR& desc,CString& name)
{
    COMMON_SYMBOL_HEADER  *varPtr;
    COMMON_BLOCK_HEADER  *blockPtr;
    HANDLE *pHdl;
    char *temp1;

    if ( NULL_SYMBOL == m_blockDesc ) return FAILURE ;
    if ( NULL_SYMBOL == m_varDesc ) return FAILURE;
    
    desc = m_varDesc ;
    if ( GOOD != SymGetSymbolName( m_varDesc , &temp1 ) )
        return FAILURE;
    name = temp1;
    if ( temp1 ) {
        pHdl = (HANDLE *)( temp1 - sizeof(HANDLE) );
        GlobalFree( *pHdl );
    }
    temp1 = 0;
        
    while ( m_blockDesc != NULL_SYMBOL ) {
        if (!UtilIsValidSymDescriptor(m_blockDesc)) {
            m_varDesc = NULL_SYMBOL;
            return GOOD;
        }
        blockPtr=(COMMON_BLOCK_HEADER *)st.GetHugeDataPtr(m_blockDesc);
        if ( ((blockPtr->symHeader.typeIndex.symType)&0x0F) == SYM_MODULE ) {
            m_varDesc = NULL_SYMBOL;
            return GOOD;
        }
        if (m_varDesc == NULL_SYMBOL) {
            m_varDesc = blockPtr->list.varListOffset ;
        }
        else {
            if (!UtilIsValidSymDescriptor(m_varDesc)) return FAILURE;
            varPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(m_varDesc);
            m_varDesc = varPtr->symSiblingOffset;
        }
        if ( m_varDesc == NULL_SYMBOL ) {
            m_blockDesc = blockPtr->symHeader.symParentOffset ;
        }
        else break;
    }
    return GOOD; 
}

/*------------------------------------------------------------------------
** stkServer::GetSourceAddr
**
** Purpose:
**    build Stack Server Information
*/
/*------------------------------------------------------------------------*/
int WINAPI StkGetSourceAddr(ADDR& addr)
{
    U32              currentSP;
    U32			     regValue;
    ADDR             start , end;
    U16              ui;
    char             *buff;                   
    RET_ADDR retAddr;

    if ( SrcIsLoaded() != GOOD ) return FAILURE;

    currentSP = 0;  

#ifdef _LINK_WITH_ABI_    
    if (ICE_OK != (emuGetReg(0 ,0, &regValue)))
        return FAILURE;
#else
	regValue = 0;
#endif                                       
    
    addr.addrType = 1;  

    if ( !SymSrcIsLibFunction((U32)regValue) ) {
        addr.addr = (U32) regValue;
//      return GOOD;
        return FAILURE;
    }    

#ifdef _LINK_WITH_ABI_    
    if (ICE_OK != (emuGetReg(0,4,&regValue)))   //Get SP
        return FAILURE;
#else
	regValue = 0;
#endif                                       
    
    currentSP = (U32) regValue;  /* save returned addr from CPU */

    buff = 0;

    if (( currentSP > 0x08L)&&( currentSP < 0x100L )) {
        regValue = (U16) (currentSP - 0x07L);
        buff = new char [ regValue ];
        if ( buff == 0 ) return FAILURE;

        start.addr = 0x08;
        end.addr = ( U16 ) currentSP ;
        start.addrType = end.addrType = 3;  // 3 -- IDATA
    
#ifdef _LINK_WITH_ABI_    
        if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(U8*)buff,&retAddr) ) {
            return FAILURE;
        }
#endif        
    }
    else if ( currentSP >= 0x100L ) return FAILURE;
    
    regValue = (U16) currentSP;  
    while ( regValue > 0x08 ) {
       
        ui = (U16) buff[ regValue - 0x08 ] ;
        ui = (ui<<8) + (U8)buff[ regValue - 0x09 ];
        
        if ( !SymSrcIsLibFunction( (U32)ui ) ) {
            break;
        }
        regValue -= 2;
    }                      
    if ( buff ) delete buff;
    if ( regValue > 0x08 ) {
        addr.addr = ui;
        return GOOD;
    }

    return FAILURE;
}

/***************************************************************************
*                                                                          *
*  U16ToStr - convert U16 to string                                        *
*  parameter :                                                             *
*       ui  --  unisgned int value ( input )                               *
*       s  --  string ( output )                                           *
*                                                                          *
***************************************************************************/
void VarU16ToStr(U16 ui,char *s)
{
    U8 uc ;
    int i;
       
    *s++ = '(';
    *s++ = '0';
    *s++ = 'x';
    for(i=0;i<4;i++) {    
        uc = (unsigned char) (ui & 0x000F);
        if( uc >= 10 ) 
            s[3-i] = (char) ('A'+uc-10);
        else
            s[3-i] = (char) ('0'+uc);
        ui = ui >> 4;
    }        
    s[4] = ')';
    s[5] = '\0';
}

/***************************************************************************
*                                                                          *
*  U32ToStr - convert U32 to string                                        *
*  parameter :                                                             *
*       ul  --  unisgned long value ( input )                              *
*       s  --  string ( output )                                           *
*                                                                          *
***************************************************************************/
void VarU32ToStr(U32 ul,char *s)
{
    U8 uc ;
    int i;
       
    *s++ = '(';
    *s++ = '0';
    *s++ = 'x';
    for(i=0;i<8;i++) {    
        uc = (unsigned char) (ul & 0x0000000FL);
        if( uc >= 10 ) 
            s[7-i] = (char)('A'+uc-10);
        else
            s[7-i] = (char)('0'+uc);
        ul = ul >> 4;
    }        
    s[8] = ')';
    s[9] = '\0';
}

/***************************************************************************
*                                                                          *
*  U8ToStr - convert U8 to string                                          *
*  parameter :                                                             *
*       ui  --  unisgned int value ( input )                               *
*       s  --  string ( output )                                           *
*                                                                          *
***************************************************************************/
void VarU8ToStr(U8 ui,char *s)
{
    U8 uc ;
    int i;
       
    *s++ = '(';
    *s++ = '0';
    *s++ = 'x';
    for(i=0;i<2;i++) {    
        uc = (unsigned char)(ui&0x0F);
        if( uc >= 10 ) 
            s[1-i] = (char)('A'+uc-10);
        else
            s[1-i] = (char)('0'+uc);
        ui = (U8) (ui >> 4);
    }        
    s[2] = ')';
    s[3] = '\0';
}

int FindNextType(TYPE_INDEX oldType , TYPE_INDEX& nextIndex)
{
    TYPE_HEADER_TYPE typeHeader;
    TYPE_INDEX typeIndex;
    char temp[256];
    
    typeIndex = oldType;    
    typeHeader.typeName = temp;  
    if (GOOD != SymGetTypeHeader(typeIndex, &typeHeader)) 
        return FAILURE;
    if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS ) {
        nextIndex = oldType ;
        return GOOD;
    }
    if ( typeHeader.t.complexType == TY_TYPE ) {
        while( 1 ) {
            TYPE_INDEX       typeNext;
                   
            if ( GOOD != SymGetTypeTypeIndex(typeIndex,&typeNext) ) {
                return FAILURE;
            }
            typeIndex = typeNext;
            if (GOOD != SymGetTypeHeader(typeIndex, &typeHeader)){
                return FAILURE;
            }
            if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS )
                break;
            else if ( typeHeader.t.complexType != TY_TYPE )
                break;
        }   
//        if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS ) {
//            return FAILURE;
//        }
    }           
    nextIndex = typeIndex;
    return GOOD;    
}

/*------------------------------------------------------------------------
** BuildEnumValue
**
** Purpose:
**    Build enum type value to String for variable server
*/
/*------------------------------------------------------------------------*/
int BuildEnumValue(TYPE_INDEX typeIndex,SEGMENTTYPE type,U32 addr,
    int nFlag , char* str )
{                                                              
    ADDR start , end;
//    char data1[8];
    TYPE_HEADER_TYPE typeHeader;
    char data[16] ;
    char temp[256];
    U16 ui;
//    int i;
    U32 ul;
    BOOLEAN isNoMatch;
    RET_ADDR retAddr;
                    
    isNoMatch = TRUE;                    
//    if ( typeIndex >= 256 ) return FAILURE;
    if ( typeIndex < 256 ) return FAILURE;
    
//    if ( SrcIsIEEE() != GOOD ) return FAILURE;
    typeHeader.typeName = temp;  
    if (GOOD != SymGetTypeHeader(typeIndex, &typeHeader)) 
        return FAILURE;
    if ( typeHeader.typeChoice != COMPLEX_TYPE_CLASS )
        return FAILURE;
    if ( typeHeader.t.complexType != TY_ENUM_C ) 
        return FAILURE;        
          
//    if ( GOOD != SymGetTypeEnum(node->typeIndex,&bit) )
//        return FAILURE;
	int nBank;
	start.addr = addr;
    switch( type ) {
    case SEG_CODE :
        nBank =(int)(start.addr >>16) ;
        start.addrType = end.addrType = MEM_P0+ nBank; 
        break;
    case SEG_DATA :
        start.addrType = end.addrType = MEM_I;
        break;
    case SEG_XDATA :
        nBank =(int)(start.addr >>16) ; 
        start.addrType = end.addrType = MEM_X0+nBank;
        break;
    case SEG_BIT :
        start.addrType = end.addrType = 6;
        break;
    case SEG_REGISTER :
        start.addrType = end.addrType = 5;
        break;
    case SEG_SFR :
        start.addrType = end.addrType = 7;
        break;
    default :
        start.addrType = end.addrType = 0;
        break;
    }   
    end.addr = start.addr+1;
#ifdef _LINK_WITH_ABI_        
    if ( ICE_OK != emuGetMemN(start,(U16)(1+end.addr-start.addr),(ULPSTR)data,&retAddr) ) {
        return FAILURE;
    }
#else 
    data[0] = 0;    
    data[1] = 0;
#endif  
    ui = *(U16*)data;
    //ui = (ui<<8) + (U8)data[1];
/*
    if ( typeIndex==BI_U16_UINT || typeIndex==BI_S16_USHORT ||
        typeIndex==BI_STACK_U || typeIndex==BI_STACK_UINT ) {
        sprintf(str,"%u ",ui);
        VarU16ToStr(ui,&str[strlen(str)] );
    }
    else {
        sprintf(str,"%d ",(int)ui);
        VarU16ToStr(ui,&str[strlen(str)] );
    }
*/    
    ul = (U32) ui;
    if ( GOOD != SymGetTypeEnumName(typeIndex,ul,temp,&isNoMatch) )
        return FAILURE;
    if ( isNoMatch == FALSE ) {
        if ( nFlag ) {
            sprintf(str , "%s ", temp);
        }
        else {
            sprintf(str , "%s,", temp);
        }
    }
    else {                    
        if ( nFlag ) {
            sprintf(str,"%u (unknown enum)",ui);
        }                                 
        else {
            sprintf(str,"%u,",ui);
        }                                 
    }        

    return GOOD;        
}

/*------------------------------------------------------------------------
** SrcIsFunction
**
** Purpose:
**    corvert string to valid symbol .
*/
/*------------------------------------------------------------------------*/
//int SrcIsFunction(const char *command, U16& uStart, U16& uEnd)
extern "C" int WINAPI SrcIsFunction(const char *command)
{
    BOOLEAN globalFlag;
    SYM_DESCRIPTOR tempDesc , moduleDesc , funcDesc ;
    
    char temp[1024];
//    int i , j , k;
//    COMMON_SYMBOL_HEADER  *funcPtr;
//    COMMON_SYMBOL_HEADER  *modPtr , *funcPtr;
//    HANDLE *pHdl;
//    char *temp1;
//    SYM_DESCRIPTOR nextDesc;
    RETCODE          err = GOOD;
    SYM_TYPE_TYPE    symType;

    if ( SrcIsLoaded() != GOOD ) return FAILURE;
                     
    symType = SYM_UNDEFINED;                     
    moduleDesc = funcDesc = NULL_SYMBOL;
    strcpy( temp , command );
                    
    globalFlag = TRUE;                  
//    isGlobal = TRUE;
//    symDesc = NULL_SYMBOL;
    
    if ( temp[0] != '#' ) return FAILURE;
    if ( temp[1] == '\0' ) return FAILURE;
    
    symType = SYM_UNDEFINED;                     
    err = SymGetSymbolFromContext(NULL_SYMBOL,
//                                  strName[0],
                                  &temp[1], 
                                  &symType,
                                  &tempDesc,
                                  &globalFlag);
    if ((GOOD == err) && (SYM_FUNCTION == symType)) {
        funcDesc = tempDesc ;
    }
    else return FAILURE;
/*    
    funcPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(funcDesc);
    if ( funcPtr == 0 ) return FAILURE;
    uStart = (U16)funcPtr->beginAddrInfo.startAddr;
    uEnd = (U16)funcPtr->endAddrInfo.endAddr;
*/
    return GOOD;
}

/*------------------------------------------------------------------------
** SrcIsFunction
**
** Purpose:
**    corvert string to valid symbol .
*/
/*------------------------------------------------------------------------*/
int SrcGetFuncRange(const char *command, U32& uStart, U32& uEnd)
{
    BOOLEAN globalFlag;
    SYM_DESCRIPTOR tempDesc , moduleDesc , funcDesc ;
    
    char temp[1024];
    COMMON_SYMBOL_HEADER  *funcPtr;
    RETCODE          err = GOOD;
    SYM_TYPE_TYPE    symType;

    if ( SrcIsLoaded() != GOOD ) return FAILURE;
                     
    symType = SYM_UNDEFINED;                     
    moduleDesc = funcDesc = NULL_SYMBOL;
    strcpy( temp , command );
                    
    globalFlag = TRUE;                  
    
    if ( temp[0] != '#' ) return FAILURE;
    if ( temp[1] == '\0' ) return FAILURE;
    
    symType = SYM_UNDEFINED;                     
    err = SymGetSymbolFromContext(NULL_SYMBOL,
//                                  strName[0],
                                  &temp[1], 
                                  &symType,
                                  &tempDesc,
                                  &globalFlag);
    if ((GOOD == err) && (SYM_FUNCTION == symType)) {
        funcDesc = tempDesc ;
    }
    else return FAILURE;
    
    funcPtr=(COMMON_SYMBOL_HEADER *)st.GetHugeDataPtr(funcDesc);
    if ( funcPtr == 0 ) return FAILURE;
    uStart = funcPtr->beginAddrInfo.startAddr;
    uEnd = funcPtr->endAddrInfo.endAddr;

    return GOOD;
}
/******************************** E O F ***********************************/
RETCODE stkServer::VarIsActive(SYM_DESCRIPTOR inputSymbol,LPSTR varName,U16& framePtr)
{
	SYM_TYPE_TYPE  symType,basicSymType=SYM_LOCAL_VAR;    
	SYM_DESCRIPTOR currentVarDesc;          
	U16 listCount;
	RETCODE err;   
	
	HPU8             symPtr;
    U32              startAddr, tmpAddrSize;
   	TYPE_HEADER_TYPE typeHeader;
   	SYM_TYPE_VARIABLE *varPtr;
    if(LdrIsUbrof()){ framePtr = stkListHeader->framePtr ; return GOOD;}
    if(stkListHeader==NULL || stkListHeader->desc==NULL) return -1;
	if(GOOD!=(err=SymGetSymbolHeadList(stkListHeader->desc,
				basicSymType,&currentVarDesc,&listCount) ) ) 
		return err;
    while (listCount--)
    {
        if(inputSymbol == currentVarDesc) 
        {
        	framePtr = stkListHeader->framePtr;
        	return GOOD;
        }
	    if ((err = SymGetSymbolSibling(currentVarDesc, &symType,
	                                  &currentVarDesc)) != GOOD)
	       return err;
  	}
	return -1;
/*
	SYM_TYPE_TYPE  symType;
    SYM_DESCRIPTOR outputSymbol,currentSymbol,parentSymbol;
    BOOLEAN        isGlobal;
    SYM_DESCRIPTOR     funcDescriptor;
    SYM_DESCRIPTOR     moduleDescriptor;
    SYM_DESCRIPTOR     parentDescriptor;
    RETCODE err;

   	currentSymbol = inputSymbol;
   funcDescriptor = moduleDescriptor = parentDescriptor = NULL_SYMBOL;
   do {
      if ((err = SymGetSymbolParent(currentSymbol, &symType, &parentSymbol))
         != GOOD)
         return err;
      if (!parentDescriptor) parentDescriptor = parentSymbol;
      if ((symType == SYM_FUNCTION)  && (!funcDescriptor))
      {
         funcDescriptor = parentSymbol;
         if(GOOD==searchFunc(parentSymbol,framePtr))  	return GOOD;
      }
      currentSymbol = parentSymbol;
   } while (TRUE);
	return -1;                     
*/	
}


RETCODE StkVarIsActive(SYM_DESCRIPTOR inputSymbol,LPSTR varName,U16& framePtr)
{
	return stkObject.VarIsActive(inputSymbol,varName,framePtr);
}


RETCODE GetFuncLocalVarBytes(SYM_DESCRIPTOR funcSymbol,U16& bytes) 
{
	SYM_TYPE_TYPE  symType,basicSymType=SYM_LOCAL_VAR;    
	SYM_DESCRIPTOR currentVarDesc;   
	U16 listCount;
	RETCODE err;   
	
	HPU8             symPtr;
    U32              startAddr, tmpAddrSize;
   	TYPE_HEADER_TYPE typeHeader;
   	SYM_TYPE_VARIABLE *varPtr;
   
   	int             n =0;
	typeHeader.typeName= new char[32];
	if(GOOD!=(err=SymGetSymbolHeadList(funcSymbol,
				basicSymType,&currentVarDesc,&listCount) ) ) 
		return err;
    while (listCount--)
    {
	   symPtr = st.GetHugeDataPtr(currentVarDesc);
	   varPtr = (SYM_TYPE_VARIABLE *)symPtr;
	   
	   switch (((COMMON_SYMBOL_HEADER HUGE *)symPtr)->typeIndex.symType & 0xF) {
	      case SYM_LOCAL_VAR:
	         if (varPtr->isConstant){
	            // if reg, get size from type info
	            if ((err = SymGetTypeHeader(varPtr->typeIndex, &typeHeader))
	                != GOOD) return err;
	            n+=typeHeader.sizeInMAUs;
	            
	            break; /* out of the switch statement */
	         }                     
	         break;
	      default: break;
	  }       
	  if ((err = SymGetSymbolSibling(currentVarDesc, &symType,
	                                  &currentVarDesc)) != GOOD)
	       return err;
  	}
	delete typeHeader.typeName;
	bytes= n;
	return GOOD;
}	

RETCODE GetFuncParamBytes(SYM_DESCRIPTOR funcSymbol,U16& bytes)
{ 
	U32              attribute;
	U8               frameType;
	U32              pushMask;
	TYPE_HEADER_TYPE returnType;
	U8               argCount;
	U8               level;
	char             fatherName[32];
	TYPE_HEADER_TYPE typeHeader;
	int i=1,n=0;    
	RETCODE err;              
	returnType.typeName= new char[32];
	typeHeader.typeName= new char[32];
	if(GOOD!=(err=SymGetFuncType(funcSymbol,
                   &attribute,
                   &frameType,
                   &pushMask,
                   &returnType,
                   &argCount,
                   &level,
                   fatherName) ))
	{
		delete returnType.typeName ;
		delete typeHeader.typeName;
		return err;
	}                   
	while(i<argCount+1)
	{
		if(GOOD!=(err=SymGetFuncParamNth(funcSymbol,i ,&typeHeader) ))
		{
			delete returnType.typeName ;
			delete typeHeader.typeName;
			return err;
		}	
		n+=typeHeader.sizeInMAUs;    i++;
	}   
	bytes= n;
	delete returnType.typeName ;
	delete typeHeader.typeName;
	return GOOD;		                                
}	  

BOOL searchList(U8* pList,U8 byte)
{
	int i=0;
	while(i<40&&pList[i]) 
	{
		if(pList[i]==byte) return TRUE;
		i++;
	}
	return FALSE;
}

RETCODE IARGetFuncLocalVarBytes(SYM_DESCRIPTOR funcSymbol,
								U16& overlayBytes,U16& autoBytes) 
{
	SYM_TYPE_TYPE  symType,basicSymType=SYM_LOCAL_VAR;    
	SYM_DESCRIPTOR currentVarDesc;   
	U16 listCount;
	RETCODE err;   
	
	HPU8             symPtr;
    U32              startAddr, tmpAddrSize;
   	TYPE_HEADER_TYPE typeHeader;
   	SYM_TYPE_VARIABLE *varPtr;
   	U8 pList[40]="";
    
//get Param List
	U32              attribute;
	U8               frameType;
	U32              pushMask;
	TYPE_HEADER_TYPE returnType;
	U8               argCount;
	U8               level;
	char             fatherName[32];
	//TYPE_HEADER_TYPE typeHeader;
	int i=1,n=0;    
    int bytes=0;          
	returnType.typeName= new char[32];
	typeHeader.typeName= new char[32];
	if(GOOD!=(err=SymGetFuncType(funcSymbol,
                   &attribute,
                   &frameType,
                   &pushMask,
                   &returnType,
                   &argCount,
                   &level,
                   fatherName) ))
	{
		delete returnType.typeName ;
		delete typeHeader.typeName;
		return err;
	}                   
/*
	while(i<argCount+1)
	{
		if(GOOD!=(err=SymGetFuncParamNth(funcSymbol,i ,&typeHeader) ))
		{
			delete returnType.typeName ;
			delete typeHeader.typeName;
			return err;
		}
		if( i==1&& typeHeader.t.complexType!=TY_STRUCT &&
			typeHeader.t.complexType!=TY_STRUCT  )
		{
			i++;	continue;	
		}	
		n+=typeHeader.sizeInMAUs;    i++;
	}   

	if(argCount>0)
	{
		if(GOOD!=(err=SymGetFuncParamNth(funcSymbol,1 ,&typeHeader) ))	
		{
				delete returnType.typeName ;
				delete typeHeader.typeName;
				return err;
		}
		bytes=typeHeader.sizeInMAUs; 
		delete returnType.typeName ;
		delete typeHeader.typeName;
	}		   
// end of param List
*/
   	autoBytes=0;
	typeHeader.typeName= new char[32];
	if(GOOD!=(err=SymGetSymbolHeadList(funcSymbol,
				basicSymType,&currentVarDesc,&listCount) ) ) 
		return err;
    U16 regIndex;    
    int nParam=0;
    i=0;    
    
    if(argCount>0)  //remove the first Parameter.
	{

	   symPtr = st.GetHugeDataPtr(currentVarDesc);
	   varPtr = (SYM_TYPE_VARIABLE *)symPtr;
	   
	   switch (((COMMON_SYMBOL_HEADER HUGE *)symPtr)->typeIndex.symType & 0xF) {
	      case SYM_LOCAL_VAR:
            if ((err = SymGetTypeHeader(varPtr->typeIndex, &typeHeader))
                != GOOD) return err;
            if (varPtr->registerClass==LIVING_REG)
            {
                regIndex = varPtr->symHeader.beginAddrInfo.registerIndex;
	         	if(regIndex>0x107&&regIndex<=0x128)
	         	{
	   				int sizeTemp;
	   				if( ( (regIndex&0x01)==0)&&( typeHeader.sizeInMAUs&0x01) )
	   					sizeTemp =typeHeader.sizeInMAUs +1;
	   				else	
	   					sizeTemp =typeHeader.sizeInMAUs;
	   				for(int j=0;j<sizeTemp;j++)
	   					if(!searchList(pList,(U8)regIndex))      		
	         				pList[i++]=(U8)regIndex++;
	         	}  
	            break; /* out of the switch statement */
	         }
	         //else if(varPtr->storageClass==AUTO_VAR_CLASS)
	         else if(varPtr->storageClass==AUTO_VAR_CLASS && nParam>=argCount)
	         {
	         	autoBytes+=	typeHeader.sizeInMAUs;
	         }
	         break;
	      default: break;
	  }  
		if ((err = SymGetSymbolSibling(currentVarDesc, &symType,
		                      &currentVarDesc)) != GOOD)
		return err;
		listCount--;nParam++;
	}
		
    while (listCount--)
    {
	   symPtr = st.GetHugeDataPtr(currentVarDesc);
	   varPtr = (SYM_TYPE_VARIABLE *)symPtr;
	   
	   switch (((COMMON_SYMBOL_HEADER HUGE *)symPtr)->typeIndex.symType & 0xF) {
	      case SYM_LOCAL_VAR:
            if ((err = SymGetTypeHeader(varPtr->typeIndex, &typeHeader))
                != GOOD) return err;
            if (varPtr->registerClass==LIVING_REG)
            {
                regIndex = varPtr->symHeader.beginAddrInfo.registerIndex;
	         	if(regIndex>0x107&&regIndex<=0x128)
	         	{
	   				int sizeTemp;
	   				if( ( (regIndex&0x01)==0)&&( typeHeader.sizeInMAUs&0x01) )
	   					sizeTemp =typeHeader.sizeInMAUs +1;
	   				else	
	   					sizeTemp =typeHeader.sizeInMAUs;
	   				for(int j=0;j<sizeTemp;j++)
	   					if(!searchList(pList,(U8)regIndex))      		
	         				pList[i++]=(U8)regIndex++;
	         	}  
	            break; /* out of the switch statement */
	         }
	         //else if(varPtr->storageClass==AUTO_VAR_CLASS)
	         else if(varPtr->storageClass==AUTO_VAR_CLASS && nParam>=argCount)
	         {
	         	autoBytes+=	typeHeader.sizeInMAUs;
	         }
	         break;
	      default: break;
	  }       
	  nParam++;	
	  if ((err = SymGetSymbolSibling(currentVarDesc, &symType,
	                                  &currentVarDesc)) != GOOD)
	       return err;
  	}               
  	
	delete typeHeader.typeName;
	overlayBytes= i;
	// new add
//	overlayBytes+=bytes;
	return GOOD;
}	

RETCODE IARGetFuncParamBytes(SYM_DESCRIPTOR funcSymbol,U16& bytes)
{ 
	U32              attribute;
	U8               frameType;
	U32              pushMask;
	TYPE_HEADER_TYPE returnType;
	U8               argCount;
	U8               level;
	char             fatherName[32];
	TYPE_HEADER_TYPE typeHeader;
	int i=1,n=0;    
	RETCODE err;              
	returnType.typeName= new char[32];
	typeHeader.typeName= new char[32];
	if(GOOD!=(err=SymGetFuncType(funcSymbol,
                   &attribute,
                   &frameType,
                   &pushMask,
                   &returnType,
                   &argCount,
                   &level,
                   fatherName) ))
	{
		delete returnType.typeName ;
		delete typeHeader.typeName;
		return err;
	}                   
	while(i<argCount+1)
	{
		if(GOOD!=(err=SymGetFuncParamNth(funcSymbol,i ,&typeHeader) ))
		{
			delete returnType.typeName ;
			delete typeHeader.typeName;
			return err;
		}
		if( i==1&& typeHeader.t.complexType!=TY_STRUCT &&
			typeHeader.t.complexType!=TY_STRUCT  )
		{
			i++;	continue;	
		}	
		n+=typeHeader.sizeInMAUs;    i++;
	}   
	bytes= n;
	delete returnType.typeName ;
	delete typeHeader.typeName;
	return GOOD;		                                
}	


int FuncFirstLine(SYM_DESCRIPTOR moduleDesc,
					SYM_DESCRIPTOR funcDesc, U32 addr)
{
	char funcName[32];
    FUNC_CLASS     funcClass;
    U32            stackSize;
    ADDR_RANGE_TYPE codeAddrRange; 
	LINENUM_TYPE          linenum;
	COLUMN_TYPE           column;
	ADDR_RANGE_TYPE       addrRange;
	LINENUM_DESCRIPTOR    index;
    U32 startAddr,endAddr;      
    int nBank;
	RETCODE err;

	if(GOOD!=(err=SymGetFunc(funcDesc, funcName,&funcClass,
				&stackSize,&codeAddrRange ) )) return err;
          
	if(GOOD!=(err=SymMapAddr2Linenum(codeAddrRange.startAddr,moduleDesc,&linenum,
					&column,&addrRange, &index) )) return err;
	if(GOOD!=(err=SymSrcLinenum2Range(moduleDesc,(U16)linenum,startAddr , 
					endAddr,nBank) )) return err;
	if(addr == startAddr) return 1;
	if(addr > endAddr) return 2;				
	return 0;
}       

void stkServer::SetStkDirty()
{
    m_isStkDirty = 1;
}  

extern "C" void WINAPI Stk_SetStkDirty()
{
	stkObject.m_isStkDirty =1 ;
	varObject.m_isStkDirty =1;
}


RETCODE stkServer::GetCurentFramePtr(SYM_DESCRIPTOR inputSymbol,LPSTR varName,U16& framePtr)
{
	SYM_TYPE_TYPE  symType,basicSymType=SYM_LOCAL_VAR;    
	SYM_DESCRIPTOR currentVarDesc;          
	U16 listCount;
	RETCODE err;   
	STKNode * pNode; 
    
    if(stkListHeader==NULL) buildStack();
	pNode=stkListHeader;
	HPU8             symPtr;
    U32              startAddr, tmpAddrSize;
   	TYPE_HEADER_TYPE typeHeader;
   	SYM_TYPE_VARIABLE *varPtr;
/*  if(LdrIsUbrof())
    { 
    	framePtr = stkListHeader->framePtr ; 
    	return GOOD;
    }
*/  
    if(pNode==NULL || pNode->desc==NULL) return -1;
	while(pNode!=NULL&&pNode->desc!=NULL)
	{ 
		if(GOOD!=(err=SymGetSymbolHeadList(pNode->desc,
					basicSymType,&currentVarDesc,&listCount) ) ) 
			return err;
	    while (listCount--)
	    {
	        if(inputSymbol == currentVarDesc) 
	        {
	        	framePtr = pNode->framePtr;
	        	return GOOD;
	        }
		    if ((err = SymGetSymbolSibling(currentVarDesc, &symType,
		                                  &currentVarDesc)) != GOOD)
		       return err;
	  	}
		pNode = pNode->next;	  	
  	}
	return -1;
}


RETCODE  VarGetCurentFramePtr(SYM_DESCRIPTOR inputSymbol,LPSTR varName,U16& framePtr)
{
	return varObject.GetCurentFramePtr(inputSymbol,varName,framePtr);
}