
/***************************************************************************
**
**    $Header:   D:/ECB2S/SRC/LOG/STKSVR.CPP   1.2.1.4   17 Apr 1997 16:02:08   ZJRD  $
**
**    $Log:   D:/ECB2S/SRC/LOG/STKSVR.CPP  $
** 
**    Rev 1.2.1.4   17 Apr 1997 16:02:08   ZJRD
** No change.
** 
**    Rev 1.2.1.3   16 Apr 1997 10:35:04   ZJRD
** No change.
** 
**    Rev 1.2.1.2   10 Apr 1997 15:44:18   ZJRD
** No change.
** 
**    Rev 1.2.1.1   03 Apr 1997 15:22:52   ZJRD
** No change.
** 
**    Rev 1.2.1.0   28 Mar 1997 10:26:52   ZJRD
** easy pack sld 2.09d
** 
**    Rev 1.1   19 Mar 1997 11:36:40   ZJRD
** No change.
** 
**    Rev 1.0   12 Mar 1997 14:50:48   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"

#ifdef _LINK_WITH_ABI_
#include "abibase.h"  
#else
typedef int STATUS;
typedef unsigned char FLAG;
typedef struct {
    FLAG addrType;
    unsigned long  addr;
} ADDR;

/* 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 "utilext.h"

#include "cpust.h"

            /***************************
            *                          *
            *        EXTERNALS         *
            *                          *
            ***************************/
extern MemPool st;

extern int GetPCBank();
extern BOOL GetCpuStatus(unsigned char & uchStatus);
extern BOOL IsLibFunction( U32 uAddr );
extern int IsSrcStatement(void);
extern void ShowLine(char *);
extern STATUS AbiGetOneReg(int iRegId, UINT* uRegValue);
extern STATUS AbiGetMemN(ADDR addr1, ADDR addr2,char* pchBuff);
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 SrcIsOMF51(void);
int FindNextType(TYPE_INDEX oldType , TYPE_INDEX& nextIndex);
int BuildEnumValue(TYPE_INDEX typeIndex,SEGMENTTYPE type,U32 addr,
    int nFlag , char* str );
int StkNumConvertToBank(int nNun);
U32 StkAddressConvertToBank(U32 nNun);

extern BOOL SrcSupportBankSwitch();

            /***************************
            *                          *
            *        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 EXPORT 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 , unsigned char& 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 );
            /**************************
            *                         *
            *    PRIVATE VARIABLES    *
            *                         *
            **************************/

//class stkServer stkObject;
class VarServer stkObject;

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;

/* 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 EXPORT StkCalcSymbolicInfo()  {

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

    currentPC = 0;

#ifdef _LINK_WITH_ABI_

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

    if (ICE_OK != (err = AbiGetOneReg(4 , &regValue)))
        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 EXPORT 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 EXPORT
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 EXPORT
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 EXPORT 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
*/
/*------------------------------------------------------------------------*/
int stkServer::buildStack()
{
    ADDRESS_TYPE     addr;
    U32              currentPC;
    RETCODE          err = GOOD;
    RETCODE          firstErr = GOOD;
//    MEM_ADDR_CLASS   memoryClass;
//    SYM_TYPE_TYPE    symbolType;
//    ADDR_RANGE_TYPE  addrRange;
    unsigned int     regValue;
    struct STKNode   *node;
    ADDR             start , end;
    SYM_DESCRIPTOR ModuleDesc;
    SYM_DESCRIPTOR FunctionDesc;
    SYM_DESCRIPTOR LowestLevelDesc;
//    U32 SymbolOffset;  /* distance from currentPC to found symbol */
    U16              ui;
    U32				 ul;
    char             data[4];
    unsigned char    uch;

	GetCpuStatus(uch);
	if ( uch  && uch!=STATUS_GOMONI ) return GOOD;
	
    deleteAll();
    if ( SrcIsLoaded() != GOOD ) return FAILURE;

#ifdef _LINK_WITH_ABI_

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

    if (ICE_OK != (err = AbiGetOneReg(0 , &regValue)))
        return FAILURE;

    int nBank = GetPCBank();
    
    ul = regValue;
    SymConvertToAddr(nBank, ul);
    
    node->addr1 = (U32) ul;
    node->addr = (U32) ul;

    if (ICE_OK != (err = AbiGetOneReg(4 , &regValue)))
        return FAILURE;
    
    node->sp = (U32) regValue;  /* save returned addr from CPU */

    if ( m_buff ) delete m_buff;
    m_buff = 0;
/*    
    if (( node->sp <= 0x08L)||( node->sp >= 0x256 )) {
        delete node;
        return FAILURE;
    }
    else {
        regValue = (unsigned int) (node->sp - 0x07L);
        m_buff = new char [ regValue ];
    }

    start.addr = 0x08;
    end.addr = ( unsigned short ) node->sp ;
    start.addrType = end.addrType = 3;  // 3 -- IDATA

    if ( ICE_OK != AbiGetMemN(start, end, m_buff) ) {
        delete node;
        return FAILURE;
    }

*/
    if (( node->sp > 0x08L)&&( node->sp < 0x100L )) {
        regValue = (unsigned int) (node->sp - 0x07L);
        m_buff = new char [ regValue ];

        start.addr = 0x08;
        end.addr = ( unsigned short ) node->sp ;
        start.addrType = end.addrType = 3;  // 3 -- IDATA
    
        if ( ICE_OK != AbiGetMemN(start, end, m_buff) ) {
            delete node;
            return FAILURE;
        }
    }
    
    regValue = (unsigned int) node->sp;  
    addr.segType = SEG_CODE;
    while ( regValue > 0x08 ) {
        currentPC = node->addr;
        addr.addr = currentPC;
//        err = SymMapAddr2Symbol(addr,
//                    &memoryClass,
//                    &symbolType,
//                    &SymbolOffset,
//                    &LowestLevelDesc,
//                    &FunctionDesc,
//                    &ModuleDesc);
        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;

            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;
        }
       
        node = new struct STKNode;
        if ( node == 0 ) return FAILURE;

		BOOL bBank = TRUE;
        ul = (U32) m_buff[ regValue - 0x08 ] ;
        if ( SrcSupportBankSwitch() ) {
            if ( GOOD == SrcIsOMF51() ) {
            	int bSpec = FALSE;
		        ul = (ul<<8) + (U8)m_buff[ regValue - 0x09 ];
            	if ( ul < 0x8000 ) {
					ul = StkAddressConvertToBank( ul );
					if ( ul != 0xFFFFFFFFL ) {
						regValue--;
//						ul--;     
						bSpec = TRUE;
					}
            	}
//				if ( !bSpec ) {
//			        ul = (U32) m_buff[ regValue - 0x08 ] ;
//					ul = (U32) StkNumConvertToBank( (int)ul );
//					if ( ul != 0xFFFFFFFFL ) ul--;
//				}            	 
            }
            else {
				ul = (U32) StkNumConvertToBank( (int)ul );
				if ( ul != 0xFFFFFFFFL ) ul--;
			}
		}
		if ( SrcSupportBankSwitch()&&ul < 4 ) {
			bBank=FALSE; 
//	        ul = (U32) m_buff[ regValue - 0x08 ] ;
	        ul = (ul<<8) + (U8)m_buff[ regValue - 0x09 ];
	        ul = (ul<<8) + (U8)m_buff[ regValue - 0x0A ];
	        regValue -= 3;
	        node->sp = regValue;
	        SymConvertToBank(ul, nBank);
	        ui = ( unsigned short ) ul;
	        start.addr = ui - 3;
	        end.addr = ui - 1;
	        start.addrType = start.addrType = (FLAG)nBank ; // code 
	        if ( ICE_OK != AbiGetMemN(start,end,data) ) {
	            delete node;
	            return FAILURE;
	        }               
	        SymConvertToAddr(nBank,ul);
	        node->addr1 = ul;
	        if ( data[0] == 0x012 ) {
	            node->addr = ul - 3;
	        }
	        else {
	            node->addr = ul - 2;
	        }
		}               
		if ( bBank ) {
	        ui = (U16) m_buff[ regValue - 0x08 ] ;
	        ui = (ui<<8) + (U8)m_buff[ regValue - 0x09 ];
	        regValue -= 2;
	        node->sp = regValue;
	        start.addr = ui - 3;
	        end.addr = ui - 1;
	        start.addrType = start.addrType = 1 ; // code 
	        if ( ICE_OK != AbiGetMemN(start,end,data) ) {
	            delete node;
	            return FAILURE;
	        }
	        node->addr1 = ui;
	        if ( data[0] == 0x012 ) {
	            node->addr = ui - 3;
	        }
	        else {
	            node->addr = ui - 2;
	        }
	    }
    }

    currentPC = node->addr;
    addr.addr = currentPC;
//    err = SymMapAddr2Symbol(addr,
//                &memoryClass,
//                &symbolType,
//                &SymbolOffset,
//                &LowestLevelDesc,
//                &FunctionDesc,
//                &ModuleDesc);
    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;
    }

#else
    return FAILURE;
#endif
    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;
            }
//          ShowLine( temp );
//          node = node->next;
        }
        ShowLine( 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() ) {
            U16 uAddr , uStart , uEnd ,uAddr1;
            U32 uTempAddr;
            int nBank , nBank1;
    
            uStart = 0xFFFFL;
            uEnd = 0;       
            uTempAddr = ((COMMON_SYMBOL_HEADER *)symPtr)->beginAddrInfo.startAddr;
            uAddr=(unsigned short) uTempAddr;
            SymConvertToBank(uTempAddr,nBank);
            GetStatementRange(nBank,uAddr,uStart,uEnd);
            uTempAddr = addr;
            uAddr1=(unsigned short) uTempAddr;
            SymConvertToBank(uTempAddr,nBank1);
            
//            if ( ( addr>=uStart ) &&  ( addr<=uEnd ) ) {
//            if ( ( uAddr>=uStart ) &&  ( uAddr<=uEnd ) ) {
            if ( (nBank1 == nBank)&&( uAddr1>=uStart )&&( uAddr1<=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;

    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 );
                    if ( start.addrType == 1 ) {
                    	U32 uTempAddr;   
                    	int nBank;
                    	uTempAddr = varAddr.fixedAddr.startAddr;
                    	SymConvertToBank(uTempAddr , nBank);
                    	start.addrType = (FLAG)nBank;
                    }
                    end.addrType = start.addrType;
                    start.addr = varAddr.fixedAddr.startAddr;
                    end.addr = (unsigned short)( start.addr+
                               (typeHeader.sizeInMAUs - 1) );
#ifdef _LINK_WITH_ABI_
                    if ( ICE_OK != AbiGetMemN(start,end,data) ) {
                        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 = (unsigned short) varAddr.fixedAddr.startAddr;
                    end.addr = start.addr+
                               (unsigned int)(typeHeader.sizeInMAUs - 1);
#ifdef _LINK_WITH_ABI_
                    if ( ICE_OK != AbiGetMemN(start,end,data) ) {
                        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;
    int i;
    
    if ( typeIndex >= 256 ) return FAILURE;
    switch( type ) {
    case SEG_CODE :
    	{   
    		int nBank;
    		SymConvertToBank( addr , nBank );
        	start.addrType = end.addrType = (FLAG)nBank;
        }
        break;
    case SEG_DATA :
        start.addrType = end.addrType = 3;
        break;
    case SEG_XDATA :
        start.addrType = end.addrType = 2;
        break;
    case SEG_BIT :
        start.addrType = end.addrType = 5;
        break;
    case SEG_REGISTER :
        start.addrType = end.addrType = 4;
        break;
    default :
        start.addrType = end.addrType = 0;
        break;
    }   
    start.addr = (unsigned short)addr ;
    switch ( typeIndex ) {
    case BI_BIT :
        end.addr = start.addr ;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != AbiGetMemN(start,end,data) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
#endif  
        uc = data[0]; 
        sprintf(str,"%u,",((unsigned int)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 != AbiGetMemN(start,end,data) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
#endif  
        if( typeIndex == BI_U8_UCHAR ) {            
            uc = data[0]; 
//            if ( (uc>=0x80)||(uc==0) )
//                sprintf(str,"%u,",((unsigned int)uc));
//            else 
//                sprintf(str,"'%c',",uc);
            if ( (uc>=0x20)&&(uc<=0x7F) )
                sprintf(str,"'%c',",uc);
            else
                sprintf(str,"%u,",((unsigned int)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 != AbiGetMemN(start,end,data) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
#endif  
        ui = (U16) data[0];
        ui = (ui<<8) + (U8)data[1];
//        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 != AbiGetMemN(start,end,data) ) {
            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];
        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 != AbiGetMemN(start,end,data) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
        data[2] = 0;
        data[3] = 0;
#endif  
        if ( 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 ( GOOD == SrcIsStatement() || GOOD == SrcIsIEEE() ) {
            end.addr = start.addr+3;
#ifdef _LINK_WITH_ABI_        
            if ( ICE_OK != AbiGetMemN(start,end,data) ) {
                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 != AbiGetMemN(start,end,data) ) {
                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 != AbiGetMemN(start,end,data) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
#endif  
        uc = data[0]; 
        sprintf(str,"%d,",((unsigned int)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;
    
//    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 = (FLAG)nBank;
        }
        break;
    case SEG_DATA :
        start.addrType = end.addrType = 3;
        break;
    case SEG_XDATA :
        start.addrType = end.addrType = 2;
        break;
    case SEG_BIT :
        start.addrType = end.addrType = 5;
        break;
    case SEG_REGISTER :
        start.addrType = end.addrType = 4;
        break;
    default :
        start.addrType = end.addrType = 0;
        break;
    }   
    start.addr = (unsigned short)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 != AbiGetMemN(start,end,data) ) {
            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;((unsigned int)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 != AbiGetMemN(start,end,data) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
#endif  
        ui = (U16) data[0];
        ui = (ui<<8) + (U8)data[1];

        ui = ui >> bit.offset ;
        uj = 1;
        for(i=0;(unsigned int)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 : // unsigned int ;
        if ( (bit.offset+bit.size)>16 ) return FAILURE;
        end.addr = start.addr+1;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != AbiGetMemN(start,end,data) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
#endif  
        ui = (U16) data[0];
        ui = (ui<<8) + (U8)data[1];

        ui = ui >> bit.offset ;
        uj = 1;
        for(i=0;(unsigned int)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, "B%d:", (int)(nBank-5) );
        	sprintf( str, "P%d:", (int)(nBank-6) );
        }
        else sprintf( str , " P:" );
        break;
    case SEG_DATA :
        sprintf( str , " I:" );
        break;
    case SEG_XDATA :
        sprintf( str , " X:" );
        break;
    case SEG_BIT :
        sprintf( str , " B:" );
        break;
    case SEG_REGISTER :
        sprintf( str , " R:" );
        break;
    default :
        sprintf( str , " U:" );
        break;
    }
    U16ToStr( (U16)addr , &str[3] );
    str[7] = ',';
    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 )
{                                                              
    ADDR             start , end;
    char data[16] ;
    char data1[8];
    U8 uc;
    U16 ui;
    U32 ul;
    float *f_p;
    double *d_p;
    int i;
    
    if ( typeIndex >= 256 ) return FAILURE;
    switch( type ) {
    case SEG_CODE :
    	{   
    		int nBank;
    		SymConvertToBank( addr , nBank );
        	start.addrType = end.addrType = (FLAG)nBank;
        }
        break;
    case SEG_DATA :
        start.addrType = end.addrType = 3;
        break;
    case SEG_XDATA :
        start.addrType = end.addrType = 2;
        break;
    case SEG_BIT :
        start.addrType = end.addrType = 5;
        break;
    case SEG_REGISTER :
        start.addrType = end.addrType = 4;
        break;
    default :
        start.addrType = end.addrType = 0;
        break;
    }   
    start.addr = (unsigned short)addr ;
    switch ( typeIndex ) {
    case BI_BIT :
        end.addr = start.addr ;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != AbiGetMemN(start,end,data) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
#endif  
        uc = data[0]; 
//        sprintf(str,"%u",((unsigned int)uc));
        sprintf(str,"%u ",((unsigned int)uc));
//        sprintf(str,"%u (0x%x)",((unsigned int)uc),((unsigned int)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 != AbiGetMemN(start,end,data) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
#endif  
        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",((unsigned int)uc));
//                sprintf(str,"%u (0x%x)",((unsigned int)uc),((unsigned int)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",((unsigned int)uc));
                sprintf(str,"%u ",((unsigned int)uc));
//                sprintf(str,"%u (0x%x)",((unsigned int)uc),((unsigned int)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 != AbiGetMemN(start,end,data) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
#endif  
        ui = (U16) data[0];
        ui = (ui<<8) + (U8)data[1];
//        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 != AbiGetMemN(start,end,data) ) {
            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];
//        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 != AbiGetMemN(start,end,data) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
        data[2] = 0;
        data[3] = 0;
#endif  
        if ( 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 ( GOOD == SrcIsStatement() || GOOD == SrcIsIEEE() ) {
            end.addr = start.addr+3;
#ifdef _LINK_WITH_ABI_        
            if ( ICE_OK != AbiGetMemN(start,end,data) ) {
                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 != AbiGetMemN(start,end,data) ) {
                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 != AbiGetMemN(start,end,data) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
#endif  
        uc = data[0]; 
//        sprintf(str,"%d",((unsigned int)uc));
        sprintf(str,"%d ",((unsigned int)uc));
//        sprintf(str,"%d (0x%x)",((unsigned int)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;
    
//    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 = (FLAG)nBank;
        }
        break;
    case SEG_DATA :
        start.addrType = end.addrType = 3;
        break;
    case SEG_XDATA :
        start.addrType = end.addrType = 2;
        break;
    case SEG_BIT :
        start.addrType = end.addrType = 5;
        break;
    case SEG_REGISTER :
        start.addrType = end.addrType = 4;
        break;
    default :
        start.addrType = end.addrType = 0;
        break;
    }   
    start.addr = (unsigned short)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 != AbiGetMemN(start,end,data) ) {
            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;(unsigned int)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 != AbiGetMemN(start,end,data) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
#endif  
        ui = (U16) data[0];
        ui = (ui<<8) + (U8)data[1];

        ui = ui >> bit.offset ;
        uj = 1;
        for(i=0;(unsigned int)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 : // unsigned int ;
        if ( (bit.offset+bit.size)>16 ) return FAILURE;
        end.addr = start.addr+1;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != AbiGetMemN(start,end,data) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
        data[1] = 0;
#endif  
        ui = (U16) data[0];
        ui = (ui<<8) + (U8)data[1];

        ui = ui >> bit.offset ;
        uj = 1;
        for(i=0;(unsigned int)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;
    
    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 = (FLAG)nBank;
        }
        break;
    case SEG_DATA :
        start.addrType = end.addrType = 3;
        break;
    case SEG_XDATA :
        start.addrType = end.addrType = 2;
        break;
    case SEG_BIT :
        start.addrType = end.addrType = 5;
        break;
    case SEG_REGISTER :
        start.addrType = end.addrType = 4;
        break;
    default :
        start.addrType = end.addrType = 0;
        break;
    }   
    start.addr = (unsigned short)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 != AbiGetMemN(start,end,data) ) {
            return FAILURE;
        }
#else 
        data[0] = 0;    
#endif  
        ui = data[0];
        ui = ui >> bit.offset ;
        uj = 1;
        for(i=0;(unsigned int)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 != AbiGetMemN(start,end,data) ) {
            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 = ui >> bit.offset ;
        uj = 1;
        for(i=0;(unsigned int)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 : // unsigned int ;
        if ( (bit.offset+bit.size)>16 ) return FAILURE;
        end.addr = start.addr+1;
#ifdef _LINK_WITH_ABI_        
        if ( ICE_OK != AbiGetMemN(start,end,data) ) {
            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 = ui >> bit.offset ;
        uj = 1;
        for(i=0;(unsigned int)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 :
    	SymConvertToBank(addr,nBank);
        if ( nBank<=9&&nBank>=6 ) {
//        	sprintf( str, "B%d:", (int)(nBank-5) );
        	sprintf( str, "P%d:", (int)(nBank-6) );
        }
        else sprintf( str , " P:" );
        break;
    case SEG_DATA :
        sprintf( str , " I:" );
        break;
    case SEG_XDATA :
        sprintf( str , " X:" );
        break;
    case SEG_BIT :
        sprintf( str , " B:" );
        break;
    case SEG_REGISTER :
        sprintf( str , " R:" );
        break;
    default :
        sprintf( str , " U:" );
        break;
    }
    U16ToStr( (U16)addr , &str[3] );
    str[7] = '\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(int nBank, U16 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;

	SymConvertToAddr(nBank,address.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(int nBank, unsigned short uAddr,unsigned short& uStart,
                unsigned short& uEnd)
{                
//    U16 addr;
    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 = (U16) uAddr;

	SymConvertToAddr(nBank,address.addr);
	
    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 = (unsigned short)modStart;
        uEnd = (unsigned short)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
*/
/*------------------------------------------------------------------------*/
int 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
*/
/*------------------------------------------------------------------------*/
int 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
*/
/*------------------------------------------------------------------------*/
int 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
*/
/*------------------------------------------------------------------------*/
int 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
*****************************************************************/
int 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
// Modified by gates Hua , for support bank-switch    
//    sprintf( temp , "%lx" , node->addr );    
//    s2 = temp; // addr
//	memset( temp, 0, 1024 );
	BuildComplexAddr( SEG_CODE , node->addr , temp );
	temp[7] = '\0';
	s2 = temp;

    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 , unsigned char& addrType )
{
    switch( type ) {
    case SEG_CODE :
        addrType = 1;
        break;
    case SEG_DATA :
        addrType = 3;
        break;
    case SEG_XDATA :
        addrType = 2;
        break;
    case SEG_BIT :
        addrType = 5;
        break;
    case SEG_REGISTER :
        addrType = 4;
        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 :
        type = SEG_DATA ;
        break;
    case 4 :
        type = SEG_REGISTER ;
        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;
//        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 GetSourceAddr(ADDR& addr)
{
    U32              currentSP;
    unsigned int     regValue;
    ADDR             start , end;
    U16              ui;
    char             *buff;

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

    currentSP = 0;  

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

	int nBank = GetPCBank();
	
    if ( !IsLibFunction(nBank, (unsigned short)regValue) ) {
        addr.addr = (unsigned short) regValue;
        return FAILURE;
    }    

	addr.addrType = (FLAG)nBank;
	
#ifdef _LINK_WITH_ABI_    
    if (ICE_OK != (AbiGetOneReg(4 , &regValue)))
        return FAILURE;
#else
	regValue = 0;
#endif                                       
    
    currentSP = (U32) regValue;  /* save returned addr from CPU */

    buff = 0;

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

        start.addr = 0x08;
        end.addr = ( unsigned short ) currentSP ;
        start.addrType = end.addrType = 3;  // 3 -- IDATA
    
#ifdef _LINK_WITH_ABI_    
        if ( ICE_OK != AbiGetMemN(start, end, buff) ) {
            return FAILURE;
        }
#endif        
    }
    else if ( currentSP >= 0x100L ) return FAILURE;
    
    regValue = (unsigned int) currentSP;  
    while ( regValue > 0x08 ) {
       
        ui = (U16) buff[ regValue - 0x08 ] ;
        ui = (ui<<8) + (U8)buff[ regValue - 0x09 ];
        
        if ( !IsLibFunction( nBank, (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;
                    
    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;
    switch( type ) {
    case SEG_CODE :
    	{   
    		int nBank;
    		SymConvertToBank( addr , nBank );
        	start.addrType = end.addrType = (FLAG)nBank;
        }
        break;
    case SEG_DATA :
        start.addrType = end.addrType = 3;
        break;
    case SEG_XDATA :
        start.addrType = end.addrType = 2;
        break;
    case SEG_BIT :
        start.addrType = end.addrType = 5;
        break;
    case SEG_REGISTER :
        start.addrType = end.addrType = 4;
        break;
    default :
        start.addrType = end.addrType = 0;
        break;
    }   
    start.addr = (unsigned short)addr ;
    end.addr = start.addr+1;
#ifdef _LINK_WITH_ABI_        
    if ( ICE_OK != AbiGetMemN(start,end,data) ) {
        return FAILURE;
    }
#else 
    data[0] = 0;    
    data[1] = 0;
#endif  
    ui = (U16) data[0];
    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)
int 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, int& nBank)
int SrcGetFuncRange(const char *command, U16& uStart, U16& uEnd, int& nBank)
{
    BOOLEAN globalFlag;
    SYM_DESCRIPTOR tempDesc , moduleDesc , funcDesc ;
    U32 uTempStart, uTempEnd;
    
    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;
    uTempStart = funcPtr->beginAddrInfo.startAddr;
    uTempEnd = funcPtr->endAddrInfo.endAddr;

	SymConvertToBank(uTempEnd,nBank);
	SymConvertToBank(uTempStart,nBank);
	uEnd = (U16)uTempEnd;
	uStart = (U16)uTempStart;
    return GOOD;
}
/******************************** E O F ***********************************/
