 
/***************************************************************************
**
**    $Header:   D:/ECB2S/SRC/LOG/TRCSERVE.CPP   1.2.1.4   17 Apr 1997 16:07:40   ZJRD  $
**
**    $Log:   D:/ECB2S/SRC/LOG/TRCSERVE.CPP  $
** 
**    Rev 1.2.1.4   17 Apr 1997 16:07:40   ZJRD
** No change.
** 
**    Rev 1.2.1.3   16 Apr 1997 10:42:22   ZJRD
** No change.
** 
**    Rev 1.2.1.2   10 Apr 1997 15:47:58   ZJRD
** No change.
** 
**    Rev 1.2.1.1   03 Apr 1997 15:27:06   ZJRD
** No change.
** 
**    Rev 1.2.1.0   28 Mar 1997 10:30:24   ZJRD
** easy pack sld 2.09d
** 
**    Rev 1.1   19 Mar 1997 11:39:42   ZJRD
** Easy Pack SLD 2.09c
** 
**    Rev 1.0   12 Mar 1997 14:52:48   ZJRD
** Initial revision.
** 
**    Rev 1.7.1.0.1.2   09 Dec 1996 10:14:00   ZJRD
** EasyPack/SLD Version 2.0P
** 
**    Rev 1.7.1.0.1.0   11 Nov 1996 12:57:16   ZJRD
** EasyPack/SLD Version 2.01
** 
**    Rev 1.7.1.6   18 Oct 1996 09:46:18   ZJRD
** EasyPack/SLD Version 2.00
** 
**    Rev 1.7.1.3   05 Sep 1996 11:24:34   ZJRD
** No change.
** 
**    Rev 1.7.1.2   02 Sep 1996 09:51:42   ZJRD
** EasyPack/SLD Version 1.9d
** 
**    Rev 1.7.1.1   28 Aug 1996 15:43:22   ZJRD
** EasyPack/SLD Version 1.9b
** 
**    Rev 1.6   10 Jun 1996 10:19:02   ZJRD
** EasyPack/SLD Version 1.20
** 
**    Rev 1.5   05 Jun 1996 14:51:08   ZJRD
** EasyPack/SLD Version 1.96
** 
**    Rev 1.4   29 May 1996 09:27:52   ZJRD
** EasyPack/SLD Version 1.95
** 
**    Rev 1.3   16 May 1996 08:59:32   ZJRD
** EasyPack/SLD Version 1.94
** 
**    Rev 1.2   10 May 1996 09:11:08   ZJRD
** EasyPack/SLD Version 1.93
** 
**    Rev 1.1   02 May 1996 10:28:46   ZJRD
** EasyPack/SLD Version 1.92
** 
**    Rev 1.31   18 Apr 1996 12:57:52   Shirley
** EasyPack/SLD Version 1.91
** 
**    Rev 1.30   12 Apr 1996 10:41:32   Shirley
** EasyPack/SLD Version 1.90
** 
**    Rev 1.24   01 Feb 1996 10:12:50   Shirley
** EasyPack/SLD Version 0.35b
** 
**    Rev 1.23   26 Jan 1996 09:17:04   Shirley
** No change.
** 
**    Rev 1.22   25 Jan 1996 13:16:58   Shirley
** EasyPack/SLD Version 0.35
** 
**    Rev 1.21   24 Jan 1996 10:38:02   Shirley
** No change.
** 
**    Rev 1.20   23 Jan 1996 11:25:08   Shirley
** EasypPack/SLD Version 0.34c
** 
**    Rev 1.18   15 Jan 1996 16:11:14   Shirley
** EasyPack/SLD Version 0.34a
** 
**    Rev 1.16   30 Nov 1995 09:09:30   Shirley
** No change.
** 
**    Rev 1.15   28 Nov 1995 15:30:22   Shirley
** No change.
** 
**    Rev 1.14   21 Nov 1995 11:20:00   Shirley
** EasyPack/SLD Version 0.31
** 
**    Rev 1.13   13 Nov 1995 09:22:44   Shirley
** No change.
** 
**    Rev 1.12   12 Nov 1995 11:33:14   Shirley
** EasyPack/SLD Version 0.24
** 
**    Rev 1.11   08 Nov 1995 16:29:44   Shirley
** No change.
** 
**    Rev 1.10   08 Nov 1995 12:43:52   Shirley
** No change.
** 
**    Rev 1.9   02 Nov 1995 10:04:46   Shirley
** EasyPack/SLD Version 0.21
** 
**    Rev 1.8   27 Oct 1995 16:47:42   Shirley
** No change.
** 
**    Rev 1.7   27 Oct 1995 13:45:44   Shirley
** EasyPack/SLD Version 0.1g
** 
**    Rev 1.6   25 Oct 1995 14:27:18   Shirley
** EasyPack/SLD Version 0.1f
** 
**    Rev 1.5   18 Oct 1995 14:51:28   Shirley
** EasyPack/SLD Version 0.1e
** 
**    Rev 1.4   13 Oct 1995 13:21:00   Shirley
** EasyPack/SLD Version 0.1d
** 
**    Rev 1.3   29 Sep 1995 09:53:18   Shirley
** No change.
** 
**    Rev 1.2   20 Sep 1995 10:54:48   Shirley
** EasyPack/SLD Version 0.1b
** 
**    Rev 1.1   15 Sep 1995 09:49:18   Shirley
** EasyPack/SLDV0.1a 
** 
**    Rev 1.0   07 Sep 1995 09:54:16   Shirley
** Initial revision.
**
****************************************************************************/

/***************************************************************************
**
** File name : TRCSERVE.CPP 
** Author:BRIGHT CHEN, Chris Fang
** Description:
**
**
**    Finished date: 1995.9.1
**    Fixed date   :1995.9.12
**                  edit void CTrigger::ShellCmd(int nArgc, char* pszArgv[])
**                  to fix the error
**                  edit void CListTrace::ListTrcModuleToShell()
**                  to fix the list module error
**    Add date:1995.10.11
**                  add  'void SetExcludeQualify(ULONG ulBegin,ULONG ulEnd,BOOL exClude);' 
**                  to fix bug.
**    modify data  : 1995.10.11
**                  modify 'CListTrace::GetCStrNum(...)' to fix bug
**    modify data  : 1996.1.8
**                  modify listAsm... to avoid error
**                   1996.1.8--1.15
**                  modify relevant procedures to support 320 trace list
**
**	  Trace on the fly:
**					for 'list' command:
**					1) 	specificion:
**					cpu status is STATUS_GO: turn trace off, then continue
**                  cpu status is STATUS_GORUN: handled just like halt
**					2)	modify routine:
**					shell: ListCmd
**					window:ListTrcDataToWnd; ListTrcInstToWnd; ListTrcCToWnd
**
**					for ice command except 'list'(event,):
**					1) 	specificion:
**					cpu status is STATUS_GO: ice command failed.
**					cpu status is STATUS_GORUN: ice command  is handled just
**												like halt.
**					2)	modify routine:
**					shell:CBusEvent::SetbyShell;CExtEvent::SetbyShell
**						  CQualify::SetbyShell;CLevel::SetbyShell;
**						  CTrigger::SetbyShell
**						  CBusEvent::Clear;CQualify::Clear;CExtEvent::Clear	
**					window:CTrcGrpEventPage::OnSet;CTrcGrpTrcctrlPage::OnSet
**						   CTrcGrpTriggerPage::OnSet;
**						   CTrcGrpFilterPage::OnSet
**
**	  Add trace on fly spec:
**					modify function ListCmd	
**    Modify the CListTrace::GetAsmStr(...) to show "interrupt" in trace asm
**					when it detect status ak in trace buffer(special for 320 
** 					and one byte long instruction of 31)
**    Copyright (C) 1995 Microtek International, Inc.
**    All Rights Reserved
**
****************************************************************************/

//////////////////////////////////                                   
//trcserve.cpp
//Bright Cheng
//95/4
//john
//95/9
//Chris Fang, 96/3
//////////////////////////////////
#include "stdafx.h"
#include "windowsx.h"
#include "stdlib.h"
#include "string.h"
#include "ctype.h"

#include "abibase.h"
#include "abitype.h"
#include "trcserve.h"
#include "bptserve.h"
#include "cpust.h" 
#include "ctrcbuf.h"
#include "hosterrs.h"
#include "uicom.h"

// Changed by Chen, 04/10/96
// in order to build all.
#include "address.h"
#include "addrapi.h"

#define INRANGE(a, b, c) 	((a)>=(b)&&(a)<=(c))
#define ISLISTFRAME(p)	(isNum(p))
#define ISEVENTDATA(p)	(isNum(p))
#define ISCOUNT(p)		(isNum(p))

extern BOOL g_bInFatalMsgBox;
extern STATUS AbiGetTimerCount(TIMER_COUNT *pTimerCount);
extern UINT GetCpuId();
extern void ShlReshowLine(char * pch, int nLen);
extern int SrcIsLoaded(void); //from symbol(gates)             
extern int LstAddr2Info(int nBank, U16 addr,U32& moduleDesc,U32& modStart,U32& modEnd,
                          U32& funcDesc, U32& funcStart,U32& funcEnd);
extern int LstGetSymbolName(LPSTR name,U32 desc);                          
void CodeHextoText(char *Hex,char *textbuff,int num);//from dad
extern unsigned char TRCGetInstLen(unsigned char  code);
extern int GetCurrentBank(void);

extern int  TRCGetInst(unsigned short,unsigned char*,unsigned char,
               unsigned char*);
extern STATUS AbiGetCpuStatus(UINT *uCpuStatus);        
extern int  StkNumConvertToBank(int ul );
                                                      
extern void ShowReadTraceCurSite(DWORD dwCurFrom);
//CSyntaxLibJ  syn;
BOOL IsPAddr(char* p);
BOOL isNum(char * p);
BOOL IsWildCardAddr(char * p);
int IsStatus(char *str);
BOOL IsKeyword(CString& key, const char* ob);

static WORD g_adr;
static WORD g_adrSpace;

static const CString g_range("range");
static const CString g_on("on");
static const CString g_off("off");
static const CString g_trace("trace");
static const CString g_timer("timer");

BOOL IsKeyword(const CString& key, const char* ob)
{
	return(!key.CompareNoCase(ob));
}

BOOL IsPAddr(char* p)
{
ADDRESS			addr;
ADDR_RETCODE	retAdr;

	retAdr=AdrTextToAddr(p, addr);
	if(retAdr!=ADR_OK)
		return FALSE;
	if(addr.adrSpace==SPACE_UNDEFINE)
		g_adrSpace=GetCurrentBank();
	else
		g_adrSpace=addr.adrSpace;
	if(g_adrSpace==1)
		g_adrSpace=0;
	g_adr=addr.adrAddress;
	return TRUE;
}

BOOL isNum(char * p)
{
int len=strlen(p), i;

	for(i=0; i<len; i++)
	{
		if(isxdigit(p[i]))
			continue;
		return FALSE;	
	}
	return TRUE;
}

BOOL IsWildCardAddr(char * p)
{
int len=strlen(p), i;

	for(i=0; i<len; i++)
	{
		if(isxdigit(p[i])||p[i]=='x'||p[i]=='X')
			continue;
		return FALSE;	
	}
	if(strchr(p, 'x')||strchr(p,'X'))
		return TRUE;
	else
		return FALSE;	
}

//this function check if the str is stuatus s f ........
//return value refers the status
//return <0 refer to not found
int IsStatus(char *str)
{
   ASSERT( str );
   CString strx=_strupr(strupr(str));
   
   if ( strx == "S") return STATUS_S;
   if ( strx == "F") return STATUS_F;
   if ( strx == "R") return STATUS_R;
   if ( strx == "W") return STATUS_W;
   if ( strx == "AK") return STATUS_AK;
   return -1;
}

// Bus Event

CBusEvent ev1(1),ev2(2);
CExtEvent ev3;

//interface to shell
void Ev1Cmd(int nArgc, char* pszArgv[])
{           
  ev1.ShellCmd(nArgc, pszArgv); 
  ev1.m_tmpBusEv.qlfyType[0] = 1;
}
                          
//interface to shell                          
void Ev2Cmd(int nArgc, char* pszArgv[])
{                                
   ev2.ShellCmd(nArgc, pszArgv); 
   ev2.m_tmpBusEv.qlfyType[0] = 2;
}
                    
//interface to shell                    
void Ev3Cmd(int nArgc, char* pszArgv[])
{                                
   ev3.ShellCmd(nArgc, pszArgv);  
   ev3.m_extEv.qlfyType[0] = 3;
}     
                    
//interface to shell                    
void EventCmd(int nArgc, char* pszArgv[])
{
  char * ArgPointTmp[40];
  int ArgMaxTmp;
  static char Argtmp[256];    
                
  Argtmp[0]=0;              
  ArgMaxTmp = nArgc;
  for (int i=0; i< ArgMaxTmp ; i++) ArgPointTmp[i] = pszArgv[i];
  
  if (1==nArgc) 
   { 
    Argtmp[0]=0;
    strcat(Argtmp,"EV1");      ArgPointTmp[0]=Argtmp;
    Ev1Cmd(nArgc,ArgPointTmp);
    Argtmp[0]=0;
    strcat(Argtmp,"EV2");      ArgPointTmp[0]=Argtmp;
    Ev2Cmd(ArgMaxTmp,ArgPointTmp); 
    Argtmp[0]=0;
    strcat(Argtmp,"EV3");      ArgPointTmp[0]=Argtmp;
    Ev3Cmd(ArgMaxTmp,ArgPointTmp); 
    return;
    }
    
  if(0 == stricmp(pszArgv[1], "1"))
   {
    Argtmp[0]=0;
    strcat(Argtmp,"EV1");      ArgPointTmp[0]=Argtmp;
    for (int i=1; i< ArgMaxTmp-1 ; i++) ArgPointTmp[i] = ArgPointTmp[i+1];
    ArgMaxTmp--;
    Ev1Cmd(ArgMaxTmp,ArgPointTmp);
    return;
    }      
   
  if(0 == stricmp(pszArgv[1], "2"))
  {
   Argtmp[0]=0;
   strcat(Argtmp,"EV2");      ArgPointTmp[0]=Argtmp;
   for (int i=1; i< ArgMaxTmp-1 ; i++) ArgPointTmp[i] = ArgPointTmp[i+1];
   ArgMaxTmp--;
   Ev2Cmd(ArgMaxTmp,ArgPointTmp);
   return;
   }
   
  if(0 == stricmp(pszArgv[1], "3"))
  {
   Argtmp[0]=0;
   strcat(Argtmp,"EV3");      ArgPointTmp[0]=Argtmp;
   for (int i=1; i< ArgMaxTmp-1 ; i++) ArgPointTmp[i] = ArgPointTmp[i+1];
   ArgMaxTmp--;
   Ev3Cmd(ArgMaxTmp,ArgPointTmp);
   return;
   }
   
  if(0 == stricmp(pszArgv[1], "CLEAR"))
  {
    Argtmp[0]=0;
    strcat(Argtmp,"EV1");      ArgPointTmp[0]=Argtmp;
    Ev1Cmd(nArgc,ArgPointTmp);
    Argtmp[0]=0;
    strcat(Argtmp,"EV2");      ArgPointTmp[0]=Argtmp;
    Ev2Cmd(ArgMaxTmp,ArgPointTmp); 
    return;
   }
         
  ShowLine("Syntax error???");
  }

//init event              
int CBusEvent::Init()
{ 
    int   nErrorID;

    nErrorID = AbiClrEvent(m_eventID);

    if(ICE_OK == nErrorID)
     {
      m_nClearflag = 1;
      return TRUE;
      }
      else        
       {
        //DisplayErrorMessageBox(nErrorID);   
        return FALSE;
        }
   return FALSE;
 }
            
//analyse the shell command                             
void CBusEvent::ShellCmd(int nArgc, char* pszArgv[])
{      
    char*  stop_at;
    void (CBusEvent::* myFunc) ();//to decide CLEAR OR ...
    int indexhere;
   
    // Assertion of the input parameters.                
    ASSERT( nArgc > 0 );
    for ( int i = 0; i <nArgc; i++ ) ASSERT( pszArgv[i] );
    
    //init                    
    m_tmpBusEv.setMode = 0; 
    m_tmpBusEv.qlfyType[4] = 0;
    m_tmpBusEv.qlfyType[6] = 0;
    m_tmpBusEv.qlfyType[8] = 0;
    m_tmpBusEv.qlfyType[9] = 0;
    m_tmpBusEv.qlfyType[10] = 0;
    myFunc=CBusEvent::ShowToShell;
    indexhere=1;
    ArgMax = nArgc;
    for (int ii=0; ii< ArgMax ; ii++) ArgPoint[ii] = pszArgv[ii];

    while(indexhere<ArgMax)
    { 
     if(0 == _stricmp(ArgPoint[indexhere], "ADDRESS") )
      { SetAddr(&indexhere); myFunc=CBusEvent::SetbyShell; }
     else
     if(0 == _stricmp(ArgPoint[indexhere], "DATUM") )
      { SetData(&indexhere); myFunc=CBusEvent::SetbyShell; }
     else
     if(0 == _stricmp(ArgPoint[indexhere], "STATUS") )
      { SetStatus(&indexhere); myFunc=CBusEvent::SetbyShell; }
     else
     if(0 == _stricmp(ArgPoint[indexhere], "COUNT") )
      {
       m_tmpBusEv.qlfyType[10]=1;
       indexhere++;
       if (ISCOUNT(ArgPoint[indexhere]) )
        { 
         m_tmpBusEv.count = (DWORD) strtoul(ArgPoint[indexhere],&stop_at,16);
         indexhere++;
         }
        else ASSERT(0);
       myFunc=CBusEvent::SetbyShell; 
       }    
     else
     if(0 == _stricmp(ArgPoint[indexhere], "CLEAR") )
      { myFunc=CBusEvent::Clear; indexhere++; }    
      
     }//while
  (this->*myFunc) ( );   
    
 }
                           
//analyse card address                           
void CBusEvent::WildCardAddr(char *pszArgv)             
{
 
   ASSERT( pszArgv );
   
   CString  str;

    // Binary or Hexadecimal wildcard code.
    if ( 'B' == toupper(*(pszArgv+strlen(pszArgv)-1)) ) 
    {
     // Binary code.
     ASSERT ( 17 == strlen(pszArgv) );
    
     str = strupr(pszArgv);        
     if(str == "XXXXXXXXXXXXXXXXB")
     {
      m_tmpBusEv.qlfyType[4] = 0;
      return;
      }
     m_tmpBusEv.addr[1][0]=0x0ffff;
     m_tmpBusEv.addr[0][0]=0;
     for ( int i = 0; i < 17-1; i++ ) 
      {
       if ( '0' != pszArgv[i] &&
         '1' != pszArgv[i] &&
         'X' != toupper(pszArgv[i]) ) ASSERT(0);
        
       if ('0'==pszArgv[i]) m_tmpBusEv.addr[0][0] &= ~((WORD)1<<(15-i));
       if ('1'==pszArgv[i]) m_tmpBusEv.addr[0][0] |= ((WORD)1<<(15-i));
       if ('X'==toupper(pszArgv[i])) m_tmpBusEv.addr[1][0] &= ~((WORD)1<<(15-i));
       }
     m_tmpBusEv.qlfyType[4] = 0x02;
     return ;
     }
    else 
    {
     // Hexidecimal code.
     ASSERT( 4 == strlen(pszArgv) ) ;
     str = strupr(pszArgv);        
     if(str == "XXXX")
      {
       m_tmpBusEv.qlfyType[4] = 0;
       return;
       }
     int i = 4096;
     int j = 1;
     m_tmpBusEv.addr[1][0] = 0x0ffff;
     m_tmpBusEv.addr[0][0] = 0;
     char* p = pszArgv;
     while ( *p ) 
      {
        if ( isxdigit(*p) || 'X' == toupper(*p) ) 
        { 
        
         if(isdigit(*p)) 
          m_tmpBusEv.addr[0][0] +=(WORD)(*p - '0')*i;
          else
          { 
           if(toupper(*p)>='A'&&toupper(*p)<='F')
           m_tmpBusEv.addr[0][0] +=(WORD)(toupper(*p) - 'A'+10)*i;
           }
           
         if('X'==toupper(*p))
          {
            switch(j)
            {
            case 1:
                m_tmpBusEv.addr[1][0] =0x0fff;
                break;
            case 2:
                m_tmpBusEv.addr[1][0] &=0xf0ff;
                break;
            case 3:
                m_tmpBusEv.addr[1][0] &=0xff0f;
                break;
            case 4:
                m_tmpBusEv.addr[1][0] &=0x0fff0;
             }    //case
            }//if
        p++;
        j++;
        i =(int)i/16;
        }
        else 
        { ASSERT(0); }
      }//WHILE    
    m_tmpBusEv.qlfyType[4] = 0x02;
    return ;  
    }//ELSE  
    return;
 }//FUNCTION
                      
//analyse card datd                      
void CBusEvent::WildCardData(char *pszArgv)             
{
 
   ASSERT( pszArgv );
   
   CString  str;

    // Binary or Hexadecimal wildcard code.
    if ( 'B' == toupper(*(pszArgv+strlen(pszArgv)-1)) ) 
    {
     // Binary code.
     ASSERT ( 9 == strlen(pszArgv) );
    
     str = strupr(pszArgv);        
     if(str == "XXXXXXXXB")
     {
      m_tmpBusEv.qlfyType[6] = 0;
      return;
      }
     m_tmpBusEv.data2=0x0ff;
     m_tmpBusEv.data1=0;
     for ( int i = 0; i < 9-1; i++ ) 
      {
       if ( '0' != pszArgv[i] &&
         '1' != pszArgv[i] &&
         'X' != toupper(pszArgv[i]) ) ASSERT(0);
        
       if ('0'==pszArgv[i]) m_tmpBusEv.data1 &= (WORD)~(1<<(7-i));
       if ('1'==pszArgv[i]) m_tmpBusEv.data1 |= (WORD)(1<<(7-i));
       if ('X'==toupper(pszArgv[i])) m_tmpBusEv.data2 &= (WORD)~(1<<(7-i));
       }
     m_tmpBusEv.qlfyType[6] = 0x02;
     return ;
     }
    else 
    {
     // Hexidecimal code.
     ASSERT( 2 == strlen(pszArgv) ) ;
     str = strupr(pszArgv);        
     if(str == "XX")
      {
       m_tmpBusEv.qlfyType[6] = 0;
       return;
       }
     int i = 16;
     int j = 1;  
     
     m_tmpBusEv.data2 = 0x0ff;
     m_tmpBusEv.data1 = 0;
     char *p=pszArgv;
     while ( *p ) 
      {
        if ( isxdigit(*p) || 'X' == toupper(*p) ) 
        { 
        
         if(isdigit(*p)) 
          m_tmpBusEv.data1 +=(WORD)(*p - '0')*i;
          else
          { 
           if(toupper(*p)>='A'&&toupper(*p)<='F')
           m_tmpBusEv.data1 +=(WORD)(toupper(*p) - 'A'+10)*i;
           }
           
         if('X'==toupper(*p))
          {
            switch(j)
            {
            case 1:
                m_tmpBusEv.data2 =0x0f;
                break;
            case 2:
                m_tmpBusEv.data2 &=0xf0;
                break;
             }    //case
            }//if
        p++;
        j++;
        i =(int)i/16;
        }
        else 
        { ASSERT(0); }
      m_tmpBusEv.qlfyType[6] = 02;  
      }//WHILE
    }//ELSE  
    return;
 }//FUNCTION 
               
//set address               
void CBusEvent::SetAddr(int* indexhere)
{
  (*indexhere)++;
  ASSERT(*indexhere<ArgMax);
  
  //for range cmd
  if(IsKeyword(g_range,ArgPoint[*indexhere]))
   {
    m_tmpBusEv.qlfyType[4] = 0x10;
    (*indexhere)++;
    ASSERT(*indexhere<ArgMax);
    if (IsPAddr(ArgPoint[*indexhere]))
     m_tmpBusEv.addr[0][0] = g_adr,
     m_tmpBusEv.addr[0][1]=g_adrSpace;
    (*indexhere)++;
    ASSERT(*indexhere<ArgMax);
    if (IsPAddr(ArgPoint[*indexhere]))
    {
     if(g_adrSpace<m_tmpBusEv.addr[0][1])
    	 	g_adrSpace=m_tmpBusEv.addr[0][1];
     m_tmpBusEv.addr[1][0] = g_adr;
     m_tmpBusEv.addr[1][1]=g_adrSpace;
    }
    (*indexhere)++;
    m_tmpBusEv.addrCount=2;
    }        
  else
  //for xaddr  
  if(IsWildCardAddr(ArgPoint[*indexhere]))
   {
    WildCardAddr(ArgPoint[*indexhere]);       
    (*indexhere)++;
    }
  else  
  //for maximum ten addresses
  if (IsPAddr(ArgPoint[*indexhere])) 
   {
    int nums=0;                       
    m_tmpBusEv.qlfyType[4] = 0x40;
    while(*indexhere<ArgMax  &&   nums<10 &&  
         IsPAddr(ArgPoint[*indexhere]))
     {
       m_tmpBusEv.addr[nums][0] = g_adr;
       m_tmpBusEv.addr[nums][1]=g_adrSpace;
      (*indexhere)++;  nums++;
      m_tmpBusEv.addrCount=(WORD)nums;
      }//while
    }//if
}//function
             
//set data             
void CBusEvent::SetData(int* indexhere)
{       
  
  char*   stop_at;
  
  (*indexhere)++;
  ASSERT(*indexhere<ArgMax);
  
  //for range cmd
  if(IsKeyword(g_range, ArgPoint[*indexhere]))
   {
    m_tmpBusEv.qlfyType[6] = 0x10;
    (*indexhere)++;
    ASSERT(*indexhere<ArgMax);
    if (ISEVENTDATA(ArgPoint[*indexhere]))
     m_tmpBusEv.data1 = (WORD)strtoul(ArgPoint[*indexhere],&stop_at,16);
    (*indexhere)++;
    ASSERT(*indexhere<ArgMax);
    if (ISEVENTDATA(ArgPoint[*indexhere]))
     m_tmpBusEv.data2 = (WORD)strtoul(ArgPoint[*indexhere],&stop_at,16);
    (*indexhere)++;
    }        
  else
  //for xaddr  
  if(IsWildCardAddr(ArgPoint[*indexhere]))
   {
    WildCardData(ArgPoint[*indexhere]);       
    (*indexhere)++;
    }
  else  
  //for one addresses
  if ( ISEVENTDATA(ArgPoint[*indexhere]) ) 
   {                              
    m_tmpBusEv.qlfyType[6] = 0x1;
    m_tmpBusEv.data1 = (WORD)strtoul(ArgPoint[*indexhere],&stop_at,16);
    (*indexhere)++;  
    }//if
}//function
          
//set status          
void CBusEvent::SetStatus(int* indexhere)
{
  int result;
  
  (*indexhere)++;              
  ASSERT(*indexhere<ArgMax);
  m_tmpBusEv.qlfyType[8] = 1;
  m_tmpBusEv.status = 0;
  
  result=IsStatus(ArgPoint[*indexhere]);
  while(*indexhere<ArgMax && result>=0) 
   {
    m_tmpBusEv.status = m_tmpBusEv.status | (((ULONG)1)<<result);
    (*indexhere)++; 
    if(*indexhere>=ArgMax) break;
    result=IsStatus(ArgPoint[*indexhere]);
    }
  }  
      
//show event in shell
void CBusEvent::ShowToShell()
{
char str[30];

    if(1 == m_nClearflag)
    {
    wsprintf(str,"EV%u is clear ",m_eventID);
    ShowLine(str);
    }
    
    else      
 /**************************************************************/   
   { 
    int i;  WORD ii;
    CString  strBit = "";
    m_nClearflag = 0;
    CString strTmp = "";
    CString   strTmp2 = "";
    switch(m_eventID)
    {
        case 1:
        m_strDisplay = "EV1 ";
        break;
        case 2:
        m_strDisplay = "EV2 ";
    }

    switch(m_busEv.qlfyType[4])
    {
        case 0x00:
         strTmp = "Address XXXXH ";
         m_strDisplay += strTmp;         
         break;
        case 0x02:
        strTmp = "Address ";
        for ( i=15;i>=0;i--)
        {
            if(0==(m_busEv.addr[1][0] & (((WORD)1)<<i) ))
            strBit = "X";
            else
            {   
            if(0==(m_busEv.addr[0][0]&(((WORD)1)<<i))) 
                strBit = "0";
            else
                strBit = "1";
            }
            strTmp += strBit;
          }//for
        strTmp += "B ";
        m_strDisplay += strTmp;
        break;    
        case 0x10:
        if(g_nBankNum==0)
        	wsprintf(strTmp.GetBuffer(40),"Address range %04X %04X ",
                m_busEv.addr[0][0],
                m_busEv.addr[1][0]);
        else
        {
        	if(m_busEv.addr[0][1]<6||m_busEv.addr[0][1]>9)
        		m_busEv.addr[0][1]=6;
        	if(m_busEv.addr[1][1]<6||m_busEv.addr[1][1]>9)
        		m_busEv.addr[1][1]=6;
        	wsprintf(strTmp.GetBuffer(40),"Address range P%d:%04X P%d:%04X ",
                m_busEv.addr[0][1]-6, m_busEv.addr[0][0],
                m_busEv.addr[1][1]-6, m_busEv.addr[1][0]);
        }
        strTmp.ReleaseBuffer();
        m_strDisplay += strTmp;            
        break;
//        case 0x20:
//        wsprintf(strTmp.GetBuffer(40),"Address ~range %04X %04X ",
//            m_busEv.addr[0][0],
//            m_busEv.addr[1][0]);
//        strTmp.ReleaseBuffer();
//        m_strDisplay += strTmp;
//        break;
        case 0x01:
        case 0x40:
        ASSERT(m_busEv.addrCount<=10);
        strTmp = "Address ";
        for (ii=0;ii<m_busEv.addrCount;ii++)
        {
	        if(g_nBankNum==0)
    	    	wsprintf(strTmp2.GetBuffer(40),"%04X ",
        	        m_busEv.addr[ii][0]);
	        else
    	    {
        		if(m_busEv.addr[ii][1]<6||m_busEv.addr[ii][1]>9)
        			m_busEv.addr[ii][1]=6;
        		wsprintf(strTmp2.GetBuffer(40),"P%d:%04X ",
                	m_busEv.addr[ii][1]-6, m_busEv.addr[ii][0]);
            }
            strTmp2.ReleaseBuffer();
            strTmp += strTmp2;
        }
        m_strDisplay += strTmp;
        break;
        default:
        ASSERT(0);
       }//switch
       
    switch(m_busEv.qlfyType[6])
    {
        case 0x00:
         strTmp = "Datum XXH ";    
         m_strDisplay += strTmp;
        break;
        case 0x02:
        strTmp = "Datum ";
        for (i=7;i>=0;i--)
        {
            if(0==(m_busEv.data2&(((ULONG)1)<<i)))
            strBit = "X";
            else
            {   
            if(0==(m_busEv.data1&(((ULONG)1)<<i))) 
                strBit = "0";
            else
                strBit = "1";
            }
            strTmp += strBit;
           }//for
        strTmp += "B ";
        m_strDisplay += strTmp;
        break;    
        case 0x10:
        wsprintf(strTmp.GetBuffer(40),"Datum range 0x%02X 0x%02X ",
        //wsprintf(strTmp.GetBuffer(40),"Datum range %u %u ",
                 (WORD)m_busEv.data1,(WORD)m_busEv.data2);
        strTmp.ReleaseBuffer();
        m_strDisplay += strTmp;
        break;
        case 0x20:
        wsprintf(strTmp.GetBuffer(40),"Datum ~range 0x%02X 0x%02X ",
        //wsprintf(strTmp.GetBuffer(40),"Datum ~range %u %u ",
                 (WORD)m_busEv.data1,(WORD)m_busEv.data2);
        strTmp.ReleaseBuffer();
        m_strDisplay += strTmp;
        break;
        case 0x01:
        wsprintf(strTmp.GetBuffer(20),"Datum 0x%02X ",(WORD)m_busEv.data1);
        //wsprintf(strTmp.GetBuffer(20),"Datum %u ",(WORD)m_busEv.data1);
        strTmp.ReleaseBuffer();
        m_strDisplay += strTmp;
        break;
        default:
        ASSERT(0);
       }//switch
    
    CString strStatus[5] =
    {
        "S ","F ","R ","W ","AK "
    };    
    
    switch(m_busEv.qlfyType[8])
    {
        case 0:
        strTmp = "";
        break;
        case 1:
                         
        strTmp = "Status ";
        for ( i=4;i>=0;i--)
         {
            if(0!=(m_busEv.status&(((ULONG)1)<<i)))
            strTmp += strStatus[i];
          }
        break;    
        default:
        ASSERT(0);
    }
    m_strDisplay += strTmp;
    
    switch(m_busEv.qlfyType[10])
     {
        case 0:
            strTmp = "";
            break;
        case 1:
            //wsprintf(strTmp.GetBuffer(20),"Count %04X",m_busEv.count);
            wsprintf(strTmp.GetBuffer(20),"Count 0x%04X",m_busEv.count);
            strTmp.ReleaseBuffer();
            break;    
        default:
            ASSERT(0);
        }
    m_strDisplay += strTmp;
/**********************************************************************/    
    if (m_strDisplay == "EV1 " || m_strDisplay == "EV2 ")
       m_strDisplay += "is clear ";
    ShowLine(m_strDisplay.GetBuffer(m_strDisplay.GetLength()));
    }
}

//clear event
void CBusEvent::Clear()
{
char  str[50];
int   nErrorID;
unsigned char status;

    GetCpuStatus(status);
	if(status==STATUS_GO)				//CPU is run
	{
		ErrGetErrorText(ER_GOFLY_ERR_MSG, str);
		ShowLine(str);
		return;
	}

    nErrorID = AbiClrEvent(m_eventID);

    if(ICE_OK == nErrorID)
    {
    	wsprintf(str,"Ev%1u is clear successfully.", m_eventID);
    	ShowLine(str);
    	m_nClearflag = 1;
    }
    else
    DisplayErrorMessage(nErrorID);
}
             
//set event in shell             
void CBusEvent::SetbyShell()
{
char  str[50];
unsigned char status;

    GetCpuStatus(status);
	if(status==STATUS_GO)				//CPU is run
	{
		ErrGetErrorText(ER_GOFLY_ERR_MSG, str);
		ShowLine(str);
		return;
	}
    int nErrorID = AbiSetEvent(m_tmpBusEv);
    if(ICE_OK == nErrorID)
    {
    	m_nClearflag = 0;
    	m_strDisplay = "";
    	memcpy(&m_busEv,&m_tmpBusEv,sizeof(BUS_EVENT));
    	wsprintf(str,"Ev%1u is set successfully.", m_eventID);
    	ShowLine(str);
    	return ;
    }
    else
    {
    	DisplayErrorMessage(nErrorID);
    	return ;
    }
}
                    
//External Event.
int CExtEvent::Init()
{                
    STATUS status;
        
    m_tmpExtEv.qlfyType[9] = 1;
    m_tmpExtEv.extrn = 0;
    status = AbiSetEvent(m_tmpExtEv);
       
    if(ICE_OK == status)
     {
      memcpy(&m_extEv,&m_tmpExtEv,sizeof(BUS_EVENT));
      m_nClearflag=0;
      return TRUE;
      }
     else         
      {
       DisplayErrorMessage(status);
       return FALSE;
       }
 }
                     
//analyse shell command                     
void CExtEvent::ShellCmd(int nArgc, char* pszArgv[])
{
    void (CExtEvent::* myFunc) ();//to decide show OR set ...
    int indexhere;
   
    // Assertion of the input parameters.                
    ASSERT( nArgc > 0 );
    for ( int i = 0; i <nArgc; i++ ) ASSERT( pszArgv[i] );
    
    //init      
    m_tmpExtEv.setMode = 0; 
    m_tmpExtEv.qlfyType[4] = 0;
    m_tmpExtEv.qlfyType[6] = 0;
    m_tmpExtEv.qlfyType[8] = 0;
    m_tmpExtEv.qlfyType[9] = 0;
    m_tmpExtEv.qlfyType[10] = 0;
    myFunc=CExtEvent::ShowToShell;
    indexhere=1;
    ArgMax = nArgc;
    for (int ii=0; ii< ArgMax ; ii++) ArgPoint[ii] = pszArgv[ii];

    while(indexhere<ArgMax)
    { 
     if(0 == _stricmp(ArgPoint[indexhere], "HIGH") )
      { 
       m_tmpExtEv.qlfyType[9] = 1;
       m_tmpExtEv.extrn = 1;
       myFunc=CExtEvent::SetbyShell; 
       indexhere++;
       }
     else
     if(0 == _stricmp(ArgPoint[indexhere], "LOW") )
      { 
       m_tmpExtEv.qlfyType[9] = 1;
       m_tmpExtEv.extrn = 0;
       myFunc=CExtEvent::SetbyShell; 
       indexhere++;
       }
     else
     if(0 == _stricmp(ArgPoint[indexhere], "CLEAR") )
      {            
       myFunc=CExtEvent::Clear; 
       indexhere++;
       }  
     }//while
     
  (this->*myFunc) ( );    
    
}
                       
//show extern event to shell                       
void CExtEvent::ShowToShell()
{
    
  if(m_extEv.qlfyType[9]==0)  
   {
    ShowLine("EV3 is clear ");
    return;
    }
  if(m_extEv.extrn==1)
   {
    ShowLine("EV3 high"); 
    return;
    }
  if(m_extEv.extrn==0)
   {
    ShowLine("EV3 low");
    return;
    }   
  ShowLine("EV3 is clear ");
  return;  
}
                            
//clear extern event                            
void CExtEvent::Clear()
{
char str[50];
int nErrorID;
unsigned char status;

    GetCpuStatus(status);
	if(status==STATUS_GO)				//CPU is run
	{
		ErrGetErrorText(ER_GOFLY_ERR_MSG, str);
		ShowLine(str);
		return;
	}

    nErrorID = AbiClrEvent(3);

    if(ICE_OK == nErrorID)
    {
    ShowLine("EV3 is clear successfully.");
    m_nClearflag = 1;
    }    
    else
    DisplayErrorMessage(nErrorID);
}
                    
//set from shell                    
void CExtEvent::SetbyShell()
{
char str[50];
unsigned char status;

    GetCpuStatus(status);
	if(status==STATUS_GO)				//CPU is run
	{
		ErrGetErrorText(ER_GOFLY_ERR_MSG, str);
		ShowLine(str);
		return;
	}
                
    status = AbiSetEvent(m_tmpExtEv);
       
    if(ICE_OK == status)
     {
      ShowLine("EV3 is set successfully ");
      memcpy(&m_extEv,&m_tmpExtEv,sizeof(BUS_EVENT));
      m_nClearflag=0;
      }
     else
      DisplayErrorMessage(status);
}
                

//Level
CLevel Le1(1), Le2(2);

static struct LVCond
{
    DWORD       dwCond;
    char*      strCond;
}levelCond[] = 
{                       
  {  0xaaaaaaaa , "ev1 "},
  {  0xcccccccc , "ev2 "},
  {  0xf0f0f0f0 , "ev3 "},     
  {  0x88888888 , "ev1 and ev2 "},
  {  0xa0a0a0a0 , "ev1 and ev3 "},
  {  0xc0c0c0c0 , "ev2 and ev3 "},
  {  0x88888888 , "ev2 and ev1 "},
  {  0xa0a0a0a0 , "ev3 and ev1 "},
  {  0xc0c0c0c0 , "ev3 and ev2 "},
  {  0xeeeeeeee , "ev1 or ev2 "},
  {  0xfafafafa , "ev1 or ev3 "},
  {  0xeeeeeeee , "ev2 or ev1 "},
  {  0xfcfcfcfc , "ev2 or ev3 "},
  {  0xfafafafa , "ev3 or ev1 "},
  {  0xfcfcfcfc , "ev3 or ev2 "},
  {  0x80808080 , "ev1 and ev2 and ev3 "},
  {  0x80808080 , "ev1 and ev3 and ev2 "},
  {  0x80808080 , "ev2 and ev1 and ev3 "},
  {  0x80808080 , "ev2 and ev3 and ev1 "},
  {  0x80808080 , "ev3 and ev1 and ev2 "},
  {  0x80808080 , "ev3 and ev2 and ev1 "},
  {  0xfefefefe , "ev1 or ev2 or ev3 "},
  {  0xfefefefe , "ev1 or ev3 or ev2 "},
  {  0xfefefefe , "ev2 or ev1 or ev3 "},
  {  0xfefefefe , "ev2 or ev3 or ev1 "},
  {  0xfefefefe , "ev3 or ev1 or ev2 "},
  {  0xfefefefe , "ev3 or ev2 or ev1 "},
  {  0xf8f8f8f8 , "ev1 and ev2 or ev3 "},
  {  0xecececec , "ev1 and ev3 or ev2 "},
  {  0xf8f8f8f8 , "ev2 and ev1 or ev3 "},
  {  0xeaeaeaea , "ev2 and ev3 or ev1 "},
  {  0xecececec , "ev3 and ev1 or ev2 "},
  {  0xeaeaeaea , "ev3 and ev2 or ev1 "},
  {  0xe0e0e0e0 , "ev1 or ev2 and ev3 "},
  {  0xc8c8c8c8 , "ev1 or ev3 and ev2 "},
  {  0xe0e0e0e0 , "ev2 or ev1 and ev3 "},
  {  0xa8a8a8a8 , "ev2 or ev3 and ev1 "},
  {  0xc8c8c8c8 , "ev3 or ev1 and ev2 "},
  {  0xa8a8a8a8 , "ev3 or ev2 and ev1 "},
  {  0          , ""                   }
  };
  
  
//added by john 95.5     
//serve to analyse the shell command
BOOL TRCIsEventID(char* pszArgv) 
{
    // Assertion of the input parameters.
    ASSERT( pszArgv );
    
    // Is "1", "2" or "3".
    if ( 0 == stricmp(pszArgv, "EV1") ||
         0 == stricmp(pszArgv, "EV2") ||
         0 == stricmp(pszArgv, "EV3") ) {
        return (TRUE);
    }
    else {
        return (FALSE);
    }

}   // End of TRCIsEventID().

  
void Lv1Cmd(int nArgc, char* pszArgv[])
{           

   Le1.SetbyShell(nArgc, pszArgv);  
}

void Lv2Cmd(int nArgc, char* pszArgv[])
{                                
    
   Le2.SetbyShell(nArgc, pszArgv);
}

void LevelCmd(int nArgc, char* pszArgv[])
{
  char * ArgPointTmp[40];
  int ArgMaxTmp;
  static char Argtmp[256];    
                
  Argtmp[0]=0;              
  ArgMaxTmp = nArgc;
  for (int i=0; i< ArgMaxTmp ; i++) ArgPointTmp[i] = pszArgv[i];
  
  if (1==nArgc) 
   { 
    Argtmp[0]=0;
    strcat(Argtmp,"LV1");      ArgPointTmp[0]=Argtmp;
    Lv1Cmd(nArgc,ArgPointTmp);
    Argtmp[0]=0;
    strcat(Argtmp,"LV2");      ArgPointTmp[0]=Argtmp;
    Lv2Cmd(ArgMaxTmp,ArgPointTmp); 
    return;
    }
    
  if(0 == stricmp(pszArgv[1], "1"))
   {
    Argtmp[0]=0;
    strcat(Argtmp,"LV1");      ArgPointTmp[0]=Argtmp;
    for (int i=1; i< ArgMaxTmp-1 ; i++) ArgPointTmp[i] = ArgPointTmp[i+1];
    ArgMaxTmp--;
    Lv1Cmd(ArgMaxTmp,ArgPointTmp);
    return;
    }      
   
  if(0 == stricmp(pszArgv[1], "2"))
  {
   Argtmp[0]=0;
   strcat(Argtmp,"LV2");      ArgPointTmp[0]=Argtmp;
   for (int i=1; i< ArgMaxTmp-1 ; i++) ArgPointTmp[i] = ArgPointTmp[i+1];
   ArgMaxTmp--;
   Lv2Cmd(ArgMaxTmp,ArgPointTmp);
   return;
   }      
  ShowLine("Syntax error???");  
  }


int CLevel::Init()  
{
    TRIGGER_LEVEL  trigLevel; 
    memcpy(&trigLevel,&m_levelStruct,sizeof(TRIGGER_LEVEL));
    int nErrorID = AbiSetTrigLevel(m_nLevelID,trigLevel);
    if (ICE_OK == nErrorID)
     {
        //added by john 95.5 to save the settings
        m_levelStructSave.TraceFlg=m_levelStruct.TraceFlg;
        m_levelStructSave.TimerFlg=m_levelStruct.TimerFlg;
        m_levelStructSave.Condition=m_levelStruct.Condition;
        return TRUE;
      }
      else          
      {
       //DisplayErrorMessageBox(nErrorID);     
       return FALSE;
       }
    return FALSE;
  }

void CLevel::SetEvLogic(int* indexhere)
{                 
 char tmp[40];
 tmp[0]=0;
 
 while(((*indexhere)<ArgMax) &&
       (( TRCIsEventID(ArgPoint[*indexhere])) || 
        (0== stricmp(ArgPoint[*indexhere],"OR")) ||
        (0== stricmp(ArgPoint[*indexhere],"AND")) ) )
  { 
   strcat(tmp,ArgPoint[*indexhere]); strcat(tmp," "); 
   (*indexhere)++;
   }
    
 for ( int i = 0; levelCond[i].strCond[0]!=0 ; i++ ) 
  {
     if ( 0 == stricmp(levelCond[i].strCond,tmp) ) 
      {
       m_levelStruct.Condition = levelCond[i].dwCond;
       return;
       }
    }
  
  return;  
  }
  
  
void CLevel::SetTraceStatus(int* indexhere)
{
 (*indexhere)++;                         
 if(*indexhere>=ArgMax) return;
 
 if(IsKeyword(g_on, ArgPoint[*indexhere]))
  {
   m_levelStruct.TraceFlg= 1;
   (*indexhere)++;
   return;
   }
 
 if(IsKeyword(g_off, ArgPoint[*indexhere]))
  {
   m_levelStruct.TraceFlg= 2;
   (*indexhere)++;
   return;
   }
 return;               
}                                
  
void CLevel::SetTimerStatus(int *indexhere)
{
 (*indexhere)++;                         
 if(*indexhere>=ArgMax) return;
 
 if(IsKeyword(g_on, ArgPoint[*indexhere]))
  {
   m_levelStruct.TimerFlg= 1;
   (*indexhere)++;
   return;
   }
 
 if(IsKeyword(g_off, ArgPoint[*indexhere]))
  {
   m_levelStruct.TimerFlg= 2;
   (*indexhere)++;
   return;
   }
 return;               
  }       
          
          
          
void CLevel::ShowToShell()
{
   //editted by john 95.7 
   if(m_nLevelID==1)  m_strDisp="Lv1 ";
   if(m_nLevelID==2)  m_strDisp="Lv2 ";
   
   for ( int i = 0; levelCond[i].strCond[0]!=0 ; i++ ) 
    {
     if ( m_levelStructSave.Condition == levelCond[i].dwCond ) 
      {
       m_strDisp += levelCond[i].strCond;
       break;
       }
     }
     
   switch(m_levelStructSave.TraceFlg)
    {
        case 0:
        m_strDisp += "";
        break;
        case 1:
        m_strDisp += " Trace on ";
        break;
        case 2:
        m_strDisp += " Trace off ";
        break;
        default:
        ASSERT(0);
    }
    
    switch(m_levelStructSave.TimerFlg)
     {
        case 0:
        m_strDisp += "";
        break;
        case 1:
        m_strDisp += " Timer on.";
        break;
        case 2:
        m_strDisp += " Timer off.";
        break;
        default:
        ASSERT(0);
      }                
    
   ShowLine(m_strDisp.GetBuffer(200)); 
   m_strDisp.ReleaseBuffer();
}

void CLevel::SetbyShell(int nArgc,char* pszArgv[])
{
//added by john
int indexhere;
int nErrorID;
unsigned char status;
char str[50];
    
    ASSERT( (nArgc>0 && nArgc<12));
    
    if ( nArgc==1 ) { ShowToShell(); return; }

    GetCpuStatus(status);
	if(status==STATUS_GO)				//CPU is run
	{
		ErrGetErrorText(ER_GOFLY_ERR_MSG, str);
		ShowLine(str);
		return;
	}
    ArgMax = nArgc;
    for (int i=0; i< ArgMax ; i++) ArgPoint[i] = pszArgv[i];
             
    indexhere=1;
    while ( indexhere<nArgc ) 
     {        
       if(TRCIsEventID(pszArgv[indexhere]))
         SetEvLogic(&indexhere);
         else
       if(IsKeyword(g_trace, pszArgv[indexhere]))
         SetTraceStatus(&indexhere);
         else
       if(IsKeyword(g_timer, pszArgv[indexhere]))
         SetTimerStatus(&indexhere); 
         else  indexhere++;
       }
    /////////////////////////////////////////////95.7
    TRIGGER_LEVEL tmpLevel;
                                              
    memcpy(&tmpLevel,&m_levelStruct,sizeof TRIGGER_LEVEL);                                          
    nErrorID = AbiSetTrigLevel(m_nLevelID,tmpLevel);
    if (ICE_OK == nErrorID)
    {
     memcpy(&m_levelStructSave,&m_levelStruct,sizeof(TRIGGER_LEVEL));
     char tmpStr[30];
     wsprintf(tmpStr,"Lv%1u is set successfully",m_nLevelID);
     ShowLine(tmpStr);
     }
     else
      DisplayErrorMessage(nErrorID);    

}   



#define MAXNO_EVLOGIC   15

//Trigger
CTrigger Trig;

void TriggerCmd(int nArgc, char* pszArgv[])
{ 
    
  Trig.ShellCmd(nArgc,pszArgv);

  }                      
                    
int CTrigger::Init()  
{                                     
    TRIGGER_LOGIC  trigLogic;
    memcpy(&trigLogic,&m_tmpTrig,sizeof(TRIGGER_LOGIC));
    
    int nErrorID = AbiSetTrigLogic(trigLogic);
    if(ICE_OK != nErrorID) return FALSE;
    
    if(m_nTmpOnOffFlg==0 || m_nTmpOnOffFlg==1)
      nErrorID = AbiSetTrigStatus(m_nTmpOnOffFlg); 
    if(ICE_OK != nErrorID) return FALSE;
    
    m_nOnOffFlg = m_nTmpOnOffFlg;
    memcpy(&m_trig,&m_tmpTrig,sizeof(TRIGGER_LOGIC));
    return TRUE;
        //DisplayErrorMessageBox(nErrorID);

 }                    
void CTrigger::ShellCmd(int nArgc, char* pszArgv[])
{
    void (CTrigger::* myFunc) ();//to decide CLEAR OR ...
    int indexhere; 
    char*  stop_at;
   
    // Assertion of the input parameters.                
    ASSERT( nArgc > 0 );
    for ( int i = 0; i <nArgc; i++ ) ASSERT( pszArgv[i] );
    
    //init
    //unsigned char RunFlgBak=m_tmpTrig.RunFlg;
    m_tmpTrig.RunFlg=0;   
                          //NOT RUN
    //m_tmpTrig.TrigFlg=2;  
                          //BACKWARD
    //m_tmpTrig.LevelCount=1;
    //m_tmpTrig.LevelID[0]=1;
    //m_nTmpOnOffFlg=0xff;
                            //not set
    
    myFunc=CTrigger::ShowToShell;
    indexhere=1;
    ArgMax = nArgc;
    for (int ii=0; ii< ArgMax ; ii++) ArgPoint[ii] = pszArgv[ii];

    while(indexhere<ArgMax)
    { 
     if(0 == _stricmp(ArgPoint[indexhere], "RUN") )
      { m_tmpTrig.RunFlg=1; myFunc=CTrigger::SetbyShell; indexhere++; }
     else
     if(0 == _stricmp(ArgPoint[indexhere], "LV1") || 
        0 == _stricmp(ArgPoint[indexhere], "LV2" ) )
      { SetLevel(&indexhere); myFunc=CTrigger::SetbyShell; }
     else
     if(0 == _stricmp(ArgPoint[indexhere], "FORWARD") )
      { m_tmpTrig.TrigFlg=1; myFunc=CTrigger::SetbyShell; indexhere++; }
     else
     if(0 == _stricmp(ArgPoint[indexhere], "BACKWARD") )
      { m_tmpTrig.TrigFlg=2; indexhere++; myFunc=CTrigger::SetbyShell; }    
     else
     if(0 == _stricmp(ArgPoint[indexhere], "CENTER") )
      { m_tmpTrig.TrigFlg=3; indexhere++; myFunc=CTrigger::SetbyShell; }  
     else
     if(0 == _stricmp(ArgPoint[indexhere], "DELAY") )
      { 
       m_tmpTrig.TrigFlg=0; 
       indexhere++; 
       m_tmpTrig.DlayCnt = (DWORD)
                           strtoul(ArgPoint[indexhere],&stop_at,16);
       indexhere++;                                 
       myFunc=CTrigger::SetbyShell;
       }  
     else
     if(0 == _stricmp(ArgPoint[indexhere], "ON") )
      {
       //m_tmpTrig.RunFlg=RunFlgBak; 
       m_nTmpOnOffFlg=1; indexhere++; myFunc=CTrigger::SetbyShell; 
       }  
     else
     if(0 == _stricmp(ArgPoint[indexhere], "OFF") )
      {                   
       //m_tmpTrig.RunFlg=RunFlgBak;
       m_nTmpOnOffFlg=0; indexhere++; myFunc=CTrigger::SetbyShell; 
       }  
      
     }//while
  (this->*myFunc) ( );   
  
 }

void CTrigger::SetLevel(int * indexhere)
{                                                
  m_tmpTrig.LevelCount=1; 
  if (0 == _stricmp(ArgPoint[*indexhere], "LV1") )
   m_tmpTrig.LevelID[0]=1;
   else
    m_tmpTrig.LevelID[0]=2;
    
  (*indexhere)++; 
  if(*indexhere>=ArgMax) return;
  
  if(0 == _stricmp(ArgPoint[*indexhere], "THEN"))
   { 
    m_tmpTrig.LevelCount=2;
    (*indexhere)++;      
    ASSERT(*indexhere<ArgMax);
    if (0 == _stricmp(ArgPoint[*indexhere], "LV1") )
     m_tmpTrig.LevelID[1]=1;
     else
      m_tmpTrig.LevelID[1]=2;
    (*indexhere)++;
    }
    
 }

void CTrigger::ShowToShell()
{
    m_strDisplay1 = "Trigger ";
    CString  strTmp = "";
    switch(m_trig.RunFlg)
    {
        case 0:
        break;
        case 1:
        strTmp = "Run ";
        break;
        default:
        ASSERT(0);
    }
    m_strDisplay1 += strTmp;
    
    strTmp="";
    switch(m_trig.LevelCount)
    {
        case 1:
        if(m_trig.LevelID[0] == 1)
            strTmp = "lv1 ";
        else if(m_trig.LevelID[0] == 2)
            strTmp = "lv2 ";
        else
            ASSERT(0);
        break;
        case 2:
        if(m_trig.LevelID[0] == 1)
            strTmp = "lv1 Then ";
        else if(m_trig.LevelID[0] == 2)
            strTmp = "lv2 Then ";
        else
            ASSERT(0);           
        if(m_trig.LevelID[1] == 1)
            strTmp += "lv1 ";
        else if(m_trig.LevelID[1] == 2)
            strTmp += "lv2 ";
        else
            ASSERT(0);    
        break;
        default:
        ASSERT(0);
    }
    m_strDisplay1 += strTmp;
    
    strTmp="";
    switch(m_trig.TrigFlg)
    {
        case 0:
        wsprintf(strTmp.GetBuffer(100),
            //"Delay %04XH ",m_trig.DlayCnt);
            "Delay 0x%04X ",m_trig.DlayCnt);
        strTmp.ReleaseBuffer();
        break;
        case 1:
        strTmp = "Forward ";
        break;
        case 2:
        strTmp = "Backward ";
        break;
        case 3:
        strTmp = "Center ";
        break;
        default:
        ASSERT(0);
    }   
    m_strDisplay1 += strTmp;
    ShowLine(m_strDisplay1.GetBuffer(m_strDisplay1.GetLength()));
    
    m_strDisplay1="Trigger ";
    strTmp="";
    if(1==m_nOnOffFlg ) strTmp="On"; else strTmp="Off";
    m_strDisplay1 += strTmp;
    
    ShowLine(m_strDisplay1.GetBuffer(m_strDisplay1.GetLength()));
 }

void CTrigger::SetbyShell()
{
char  str[50];
unsigned char status;

    GetCpuStatus(status);
	if(status==STATUS_GO)				//CPU is run
	{
		ErrGetErrorText(ER_GOFLY_ERR_MSG, str);
		ShowLine(str);
		return;
	}

    TRIGGER_LOGIC  trigLogic;
    memcpy(&trigLogic,&m_tmpTrig,sizeof(TRIGGER_LOGIC));
    int nErrorID = AbiSetTrigLogic(trigLogic);
    if(ICE_OK == nErrorID)
     if(m_nTmpOnOffFlg==0 || m_nTmpOnOffFlg==1)
      nErrorID = AbiSetTrigStatus(m_nTmpOnOffFlg);
    if (ICE_OK == nErrorID)
     {
      ShowLine("Trigger set OK!");
      m_nOnOffFlg = m_nTmpOnOffFlg;
      memcpy(&m_trig,&m_tmpTrig,sizeof(TRIGGER_LOGIC));
      }
      else
       DisplayErrorMessage(nErrorID);
}    

//Qualify
CQualify  qlfy;

void QualifyCmd(int nArgc,char* pszArgv[])
{
  qlfy.ShellCmd(nArgc, pszArgv);
 }
                                
int CQualify::Init()
{ 
    int nErrorID = AbiClrQualify();
    if(ICE_OK == nErrorID)
     {
      m_nClearflag = 1;
      return TRUE;
      }
     else
     {
      //DisplayErrorMessageBox(nErrorID);                                    
      return FALSE;
      }
  return FALSE;    
                                     
 }                                
void CQualify::ShellCmd(int nArgc, char* pszArgv[])
{
    void (CQualify::* myFunc) ();//to decide CLEAR OR ...
    int indexhere;
   
    // Assertion of the input parameters.                
    ASSERT( nArgc > 0 );
    for ( int i = 0; i <nArgc; i++ ) ASSERT( pszArgv[i] );
    
    //init     
    m_tmpQlfy.setMode = 0; 
    m_tmpQlfy.qlfyType[0] = 0;
    m_tmpQlfy.qlfyType[4] = 0;
    m_tmpQlfy.qlfyType[6] = 0;
    m_tmpQlfy.qlfyType[8] = 0;
    m_tmpQlfy.qlfyType[9] = 0;
    m_tmpQlfy.qlfyType[10] = 0;
    myFunc=CQualify::ShowToShell;
    indexhere=1;
    ArgMax = nArgc;
    for (int ii=0; ii< ArgMax ; ii++) ArgPoint[ii] = pszArgv[ii];

    while(indexhere<ArgMax)
    { 
     if(0 == _stricmp(ArgPoint[indexhere], "ADDRESS") )
      { SetAddr(&indexhere); myFunc=CQualify::SetbyShell; }
     else
     if(0 == _stricmp(ArgPoint[indexhere], "DATUM") )
      { SetData(&indexhere); myFunc=CQualify::SetbyShell; }
     else
     if(0 == _stricmp(ArgPoint[indexhere], "STATUS") )
      { SetStatus(&indexhere); myFunc=CQualify::SetbyShell; }
     else
     if(0 == _stricmp(ArgPoint[indexhere], "CLEAR") )
      { myFunc=CQualify::Clear; indexhere++; }    
      
     }//while
  (this->*myFunc) ( );   

 }

void CQualify::WildCardAddr(char *pszArgv)             
{
 
   ASSERT( pszArgv );
   
   CString  str;

    // Binary or Hexadecimal wildcard code.
    if ( 'B' == toupper(*(pszArgv+strlen(pszArgv)-1)) ) 
    {
     // Binary code.
     ASSERT ( 17 == strlen(pszArgv) );
    
     str = strupr(pszArgv);        
     if(str == "XXXXXXXXXXXXXXXXB")
     {
      m_tmpQlfy.qlfyType[4] = 0;
      return;
      }
     m_tmpQlfy.addr[1][0]=0x0ffff;
     m_tmpQlfy.addr[0][0]=0;
     for ( int i = 0; i < 17-1; i++ ) 
      {
       if ( '0' != pszArgv[i] &&
         '1' != pszArgv[i] &&
         'X' != toupper(pszArgv[i]) ) ASSERT(0);
        
       if ('0'==pszArgv[i]) m_tmpQlfy.addr[0][0] &= ~((WORD)1<<(15-i));
       if ('1'==pszArgv[i]) m_tmpQlfy.addr[0][0] |= ((WORD)1<<(15-i));
       if ('X'==toupper(pszArgv[i])) m_tmpQlfy.addr[1][0] &= ~((WORD)1<<(15-i));
       }
     m_tmpQlfy.qlfyType[4] = 0x02;
     return ;
     }
    else 
    {
     // Hexidecimal code.
     ASSERT( 4 == strlen(pszArgv) ) ;
     str = strupr(pszArgv);        
     if(str == "XXXX")
      {
       m_tmpQlfy.qlfyType[4] = 0;
       return;
       }
     int i = 4096;
     int j = 1;
     m_tmpQlfy.addr[1][0] = 0x0ffff;
     m_tmpQlfy.addr[0][0] = 0;
     char* p = pszArgv;
     while ( *p ) 
      {
        if ( isxdigit(*p) || 'X' == toupper(*p) ) 
        { 
        
         if(isdigit(*p)) 
          m_tmpQlfy.addr[0][0] +=(WORD)(*p - '0')*i;
          else
          { 
           if(toupper(*p)>='A'&&toupper(*p)<='F')
           m_tmpQlfy.addr[0][0] +=(WORD)(toupper(*p) - 'A'+10)*i;
           }
           
         if('X'==toupper(*p))
          {
            switch(j)
            {
            case 1:
                m_tmpQlfy.addr[1][0] =0x0fff;
                break;
            case 2:
                m_tmpQlfy.addr[1][0] &=0xf0ff;
                break;
            case 3:
                m_tmpQlfy.addr[1][0] &=0xff0f;
                break;
            case 4:
                m_tmpQlfy.addr[1][0] &=0x0fff0;
             }    //case
            }//if
        p++;
        j++;
        i =(int)i/16;
        }
        else 
        { ASSERT(0); }
      }//WHILE    
    m_tmpQlfy.qlfyType[4] = 0x02;
    return ;  
    }//ELSE  
    return;
 }//FUNCTION
 
void CQualify::WildCardData(char *pszArgv)             
{
 
   ASSERT( pszArgv );
   
   CString  str;

    // Binary or Hexadecimal wildcard code.
    if ( 'B' == toupper(*(pszArgv+strlen(pszArgv)-1)) ) 
    {
     // Binary code.
     ASSERT ( 9 == strlen(pszArgv) );
    
     str = strupr(pszArgv);        
     if(str == "XXXXXXXXB")
     {
      m_tmpQlfy.qlfyType[6] = 0;
      return;
      }
     m_tmpQlfy.data2=0x0ff;
     m_tmpQlfy.data1=0;
     for ( int i = 0; i < 9-1; i++ ) 
      {
       if ( '0' != pszArgv[i] &&
         '1' != pszArgv[i] &&
         'X' != toupper(pszArgv[i]) ) ASSERT(0);
        
       if ('0'==pszArgv[i]) m_tmpQlfy.data1 &= (WORD)~(1<<(7-i));
       if ('1'==pszArgv[i]) m_tmpQlfy.data1 |= (WORD)(1<<(7-i));
       if ('X'==toupper(pszArgv[i])) m_tmpQlfy.data2 &= (WORD)~(1<<(7-i));
       }
     m_tmpQlfy.qlfyType[6] = 0x02;
     return ;
     }
    else 
    {
     // Hexidecimal code.
     ASSERT( 2 == strlen(pszArgv) ) ;
     str = strupr(pszArgv);        
     if(str == "XX")
      {
       m_tmpQlfy.qlfyType[6] = 0;
       return;
       }
     int i = 16;
     int j = 1;  
     
     m_tmpQlfy.data2 = 0x0ff;
     m_tmpQlfy.data1 = 0;
     char *p=pszArgv;
     while ( *p ) 
      {
        if ( isxdigit(*p) || 'X' == toupper(*p) ) 
        { 
        
         if(isdigit(*p)) 
          m_tmpQlfy.data1 +=(WORD)(*p - '0')*i;
          else
          { 
           if(toupper(*p)>='A'&&toupper(*p)<='F')
           m_tmpQlfy.data1 +=(WORD)(toupper(*p) - 'A'+10)*i;
           }
           
         if('X'==toupper(*p))
          {
            switch(j)
            {
            case 1:
                m_tmpQlfy.data2 =0x0f;
                break;
            case 2:
                m_tmpQlfy.data2 &=0xf0;
                break;
             }    //case
            }//if
        p++;
        j++;
        i =(int)i/16;
        }
        else 
        { ASSERT(0); }
      m_tmpQlfy.qlfyType[6] = 02;  
      }//WHILE
    }//ELSE  
    return;
 }//FUNCTION 

void CQualify::SetAddr(int* indexhere)
{       
  (*indexhere)++;
  ASSERT(*indexhere<ArgMax);
  
  //for range cmd
  if(IsKeyword(g_range, ArgPoint[*indexhere]))
   {
    m_tmpQlfy.qlfyType[4] = 0x10;
    (*indexhere)++;
    ASSERT(*indexhere<ArgMax);
    if (IsPAddr(ArgPoint[*indexhere]))
     m_tmpQlfy.addr[0][0] = g_adr,
     m_tmpQlfy.addr[0][1]=g_adrSpace;
    (*indexhere)++;
    ASSERT(*indexhere<ArgMax);
    if (IsPAddr(ArgPoint[*indexhere]))
    {
     if(g_adrSpace<m_tmpQlfy.addr[0][1])
     	g_adrSpace=m_tmpQlfy.addr[0][1];
     m_tmpQlfy.addr[1][0] = g_adr;
     m_tmpQlfy.addr[1][1]=g_adrSpace;
    }
    (*indexhere)++;
    m_tmpQlfy.addrCount=2;
    }        
  else
  //for xaddr  
  if(IsWildCardAddr(ArgPoint[*indexhere]))
   {
    WildCardAddr(ArgPoint[*indexhere]);       
    (*indexhere)++;
    }
  else  
  //for maximum ten addresses
  if ( IsPAddr(ArgPoint[*indexhere]))
   {                              
    int nums=0;                       
    m_tmpQlfy.qlfyType[4] = 0x40;
    while(*indexhere<ArgMax  &&   nums<10 &&  
         IsPAddr(ArgPoint[*indexhere]))
     {
      if (IsPAddr(ArgPoint[*indexhere]))
       m_tmpQlfy.addr[nums][0] = g_adr,
       m_tmpQlfy.addr[nums][1]=g_adrSpace;
      (*indexhere)++;  nums++;
      m_tmpQlfy.addrCount=(WORD)nums;
      
      }//while
    }//if
}//function

void CQualify::SetData(int* indexhere)
{       
  
  char*   stop_at;
  
  (*indexhere)++;
  ASSERT(*indexhere<ArgMax);
  
  //for range cmd
  if(IsKeyword(g_range, ArgPoint[*indexhere]))
   {
    m_tmpQlfy.qlfyType[6] = 0x10;
    (*indexhere)++;
    ASSERT(*indexhere<ArgMax);
    if (ISEVENTDATA(ArgPoint[*indexhere]))  
     m_tmpQlfy.data1 = (WORD)strtoul(ArgPoint[*indexhere],&stop_at,16);
    (*indexhere)++;
    ASSERT(*indexhere<ArgMax);
    if (ISEVENTDATA(ArgPoint[*indexhere]))  
     m_tmpQlfy.data2 = (WORD)strtoul(ArgPoint[*indexhere],&stop_at,16);
    (*indexhere)++;
    }        
  else
  //for xaddr  
  if(IsWildCardAddr(ArgPoint[*indexhere]))
   {
    WildCardData(ArgPoint[*indexhere]);       
    (*indexhere)++;
    }
  else  
  //for one addresses
  if ( ISEVENTDATA(ArgPoint[*indexhere]) ) 
   {                              
    m_tmpQlfy.qlfyType[6] = 0x1;
    m_tmpQlfy.data1 = (WORD)strtoul(ArgPoint[*indexhere],&stop_at,16);
    (*indexhere)++;  
    }//if
}//function

void CQualify::SetStatus(int* indexhere)
{
  int result;
  
  (*indexhere)++;              
  ASSERT(*indexhere<ArgMax);
  m_tmpQlfy.qlfyType[8] = 1;
  m_tmpQlfy.status = 0;
  
  result=IsStatus(ArgPoint[*indexhere]);
  while(*indexhere<ArgMax && result>=0) 
   {
    m_tmpQlfy.status = m_tmpQlfy.status | (((ULONG)1)<<result);
    (*indexhere)++; 
    if(*indexhere>=ArgMax) break;
    result=IsStatus(ArgPoint[*indexhere]);
    }
  }  


 
void CQualify::SetbyShell()
{

char str[50];
int nErrorID;
unsigned char status;

    GetCpuStatus(status);
	if(status==STATUS_GO)				//CPU is run
	{
		ErrGetErrorText(ER_GOFLY_ERR_MSG, str);
		ShowLine(str);
		return;
	}

    nErrorID = AbiSetQualify(m_tmpQlfy);
    if (ICE_OK == nErrorID)
    {
     memcpy(&m_qlfy,&m_tmpQlfy,sizeof QUALIFY);
     m_nClearflag = 0;
     }
     else
      DisplayErrorMessage(nErrorID);    

}

void CQualify::ShowToShell()
{
  if(m_nClearflag)
   {
    ShowLine("Qualify is clear");
    return;
    } 
  //*******************************************************
  { 
    int i;  WORD ii;
    CString  strBit = "";
    m_nClearflag = 0;
    CString strTmp = "";
    CString   strTmp2 = "";
    m_strDisplay="Qualify ";

    switch(m_qlfy.qlfyType[4])
    {
        case 0x00:
         strTmp = "Address XXXXH ";
         m_strDisplay += strTmp;
        break;
        case 0x02:
        strTmp = "Address ";
        for ( i=15;i>=0;i--)
        {
            if(0==(m_qlfy.addr[1][0] & (((WORD)1)<<i) ))
            strBit = "X";
            else
            {   
            if(0==(m_qlfy.addr[0][0]&(((WORD)1)<<i))) 
                strBit = "0";
            else
                strBit = "1";
            }
            strTmp += strBit;
          }//for
        strTmp += "B ";
        m_strDisplay += strTmp;
        break;    
       case 0x10:
        if(g_nBankNum==0)
        	wsprintf(strTmp.GetBuffer(40),"Address range %04X %04X ",
                m_qlfy.addr[0][0],
                m_qlfy.addr[1][0]);
        else
        {
        	if(m_qlfy.addr[0][1]<6||m_qlfy.addr[0][1]>9)
        		m_qlfy.addr[0][1]=6;
        	if(m_qlfy.addr[1][1]<6||m_qlfy.addr[1][1]>9)
        		m_qlfy.addr[1][1]=6;
        	wsprintf(strTmp.GetBuffer(40),"Address range P%d:%04X P%d:%04X ",
                m_qlfy.addr[0][1]-6, m_qlfy.addr[0][0],
                m_qlfy.addr[1][1]-6, m_qlfy.addr[1][0]);
        }
        strTmp.ReleaseBuffer();
        m_strDisplay += strTmp;            
        break;
//        case 0x20:
//        wsprintf(strTmp.GetBuffer(40),"Address ~range %04X %04X ",
//            m_qlfy.addr[0][0],
//            m_qlfy.addr[1][0]);
//        strTmp.ReleaseBuffer();
//        m_strDisplay += strTmp;
//        break;
        case 0x01:
        case 0x40:
        ASSERT(m_qlfy.addrCount<=10);
        strTmp = "Address ";
        for (ii=0;ii<m_qlfy.addrCount;ii++)
        {
	        if(g_nBankNum==0)
    	    	wsprintf(strTmp2.GetBuffer(40),"%04X ",
        	        m_qlfy.addr[ii][0]);
	        else
    	    {
        		if(m_qlfy.addr[ii][1]<6||m_qlfy.addr[ii][1]>9)
        			m_qlfy.addr[ii][1]=6;
        		wsprintf(strTmp2.GetBuffer(40),"P%d:%04X ",
                	m_qlfy.addr[ii][1]-6, m_qlfy.addr[ii][0]);
            }
            strTmp2.ReleaseBuffer();
            strTmp += strTmp2;
        }
        m_strDisplay += strTmp;
        break;
        default:
        ASSERT(0);
       }//switch
       
    switch(m_qlfy.qlfyType[6])
    {
        case 0x00:
         strTmp = "Datum XXH ";
         m_strDisplay += strTmp;
        break;
        case 0x02:
        strTmp = "Datum ";
        for (i=7;i>=0;i--)
        {
            if(0==(m_qlfy.data2&(((ULONG)1)<<i)))
            strBit = "X";
            else
            {   
            if(0==(m_qlfy.data1&(((ULONG)1)<<i))) 
                strBit = "0";
            else
                strBit = "1";
            }
            strTmp += strBit;
           }//for
        strTmp += "B ";
        m_strDisplay += strTmp;
        break;    
        case 0x10:
        wsprintf(strTmp.GetBuffer(40),"Datum range 0x%02X 0x%02X ",
        //wsprintf(strTmp.GetBuffer(40),"Datum range %u %u ",
                 (WORD)m_qlfy.data1,(WORD)m_qlfy.data2);
        strTmp.ReleaseBuffer();
        m_strDisplay += strTmp;
        break;
        case 0x20:
        wsprintf(strTmp.GetBuffer(40),"Datum ~range 0x%02X 0x%02X ",
        //wsprintf(strTmp.GetBuffer(40),"Datum ~range %u %u ",
                 (WORD)m_qlfy.data1,(WORD)m_qlfy.data2);
        strTmp.ReleaseBuffer();
        m_strDisplay += strTmp;
        break;
        case 0x01:
        wsprintf(strTmp.GetBuffer(20),"Datum 0x%02X ",(WORD)m_qlfy.data1);
        //wsprintf(strTmp.GetBuffer(20),"Datum %u ",(WORD)m_qlfy.data1);
        strTmp.ReleaseBuffer();
        m_strDisplay += strTmp;
        break;
        default:
        ASSERT(0);
       }//switch
    
    CString strStatus[5] =
    {
        "S ","F ","R ","W ","AK "
    };    
    
    switch(m_qlfy.qlfyType[8])
    {
        case 0:
        strTmp = "";
        break;
        case 1:
                         
        strTmp = "Status ";
        for ( i=4;i>=0;i--)
         {
            if(0!=(m_qlfy.status&(((ULONG)1)<<i)))
            strTmp += strStatus[i];
          }
        break;    
        default:
        ASSERT(0);
    }
    m_strDisplay += strTmp;
    
/**********************************************************************/    
    if(m_strDisplay=="Qualify ") m_strDisplay +="is clear";
    ShowLine(m_strDisplay.GetBuffer(m_strDisplay.GetLength()));
    }
    
}

void CQualify::Clear()
{
char		errmsg[50];
unsigned char status;

    GetCpuStatus(status);
	if(status==STATUS_GO)				//CPU is run
	{
		ErrGetErrorText(ER_GOFLY_ERR_MSG, errmsg);
		ShowLine(errmsg);
		return;
	}

    int nErrorID = AbiClrQualify();
    if(ICE_OK == nErrorID)
     {
      m_nClearflag = 1;  
      ShowLine("Clear Qualify ok!");
      }
     else
      DisplayErrorMessage(nErrorID);
}

//TimerCmd
unsigned char timerStatus = 1;     // default: on

void TimerWnd(unsigned char timer)
{             
 int nErrorID;                        
 timerStatus = timer;
 nErrorID = AbiSetTimerStatus(timerStatus);
 if(ICE_OK != nErrorID)
    ErrDisplayError(ER_ICE_OK+nErrorID);

 }

void TimerCmd(int nArgc, char* pszArgv[])
{
int nErrorID;
CString str;      
UINT uCpuStatus;

    switch(nArgc)
    {
    case 1:  
        nErrorID = AbiGetCpuStatus(&uCpuStatus);
        if(ICE_OK != nErrorID)
        {
        DisplayErrorMessage(nErrorID);
        break;
        }
        uCpuStatus &= 0x0100;
        if(uCpuStatus==0x0100)      
         timerStatus = 1;   
         else timerStatus = 0;
         
        if(timerStatus == 1)
        ShowLine("Timer on.");
        else
        ShowLine("Timer off.");
        break;
    case 2:
        str = strupr(pszArgv[1]);
        if("ON"==str)
        timerStatus = 1;
        else
        timerStatus = 0;
        nErrorID = AbiSetTimerStatus(timerStatus);
        if(ICE_OK == nErrorID)
        ShowLine("Timer set ok!");
        else
        DisplayErrorMessage(nErrorID);
        break;
    default:
        ShowLine("Syntax error???");
    }                                    
}                           

//TraceCmd
unsigned char traceStatus = 0;     // default: off

void TraceWnd(unsigned char trace)
{                 
int nErrorID;
	
	nErrorID = AbiSetTraceStatus(trace);
	if(ICE_OK != nErrorID)
    {
    	g_bInFatalMsgBox=TRUE;
    	ErrDisplayError(ER_ICE_OK+nErrorID);
    	g_bInFatalMsgBox=FALSE;
    }
	else
		GetXviewAppJohn()->m_bTraceOn=traceStatus = trace;
}

void TraceCmd(int nArgc, char* pszArgv[])
{
int nErrorID;
CString  str;     
UINT uCpuStatus;

    switch(nArgc)
    {
    case 1:
        nErrorID = AbiGetCpuStatus(&uCpuStatus);
        if(ICE_OK != nErrorID)
        {
        DisplayErrorMessage(nErrorID);
        break;
        }
        uCpuStatus &= 0x0004;
        if(uCpuStatus==0x0004)      
         traceStatus = 1;   
         else traceStatus = 0;
        if(traceStatus==1) 
        ShowLine("Trace on.");
        else
        ShowLine("Trace off.");
        break;
    case 2:
        str = strupr(pszArgv[1]);        
        if("CLEAR"==str)
        {
        	g_bTraceClear=TRUE;
        	ShowLine("Trace buffer clear OK!");
        	break;
        }
        if("ON"==str)
        	traceStatus = 1;
        else
        	traceStatus = 0;
        nErrorID = AbiSetTraceStatus(traceStatus);
        if(ICE_OK == nErrorID)
        {
        	ShowLine("Trace set OK!");
        	GetXviewAppJohn()->m_bTraceOn=(BOOL)traceStatus;
        }	
        else
        DisplayErrorMessage(nErrorID);
        break;
    case 10:
    	nErrorID = AbiSetTraceStatus(0);
        if(ICE_OK != nErrorID)
	        DisplayErrorMessage(nErrorID);
        break;
    default:
        ShowLine("Syntax error???");
    }
}

//ListTrace
//BusEvorQlfy  sQlfy;
QUALIFY      sQlfy;
CListTrace  ListTrace;
CListTrace*  pTrcSvr=&ListTrace;
CSrcFile     SrcFile;

void ListCmd(int nArgc,char* pszArgv[])
{      
unsigned char	status;    

    if(!GetCpuStatus(status))
    	return;
	if(status==STATUS_GO)				//CPU is run
		TraceCmd(10, NULL);					//TRACE OFF
	ListTrace.CmdShell(nArgc,pszArgv);
  //ListTrace.CmdShellx();
  return;
}  

                          
void CListTrace::CmdShellx()
{ 
 UCHAR count;         
 FLAG readEnd;         
 SetExcludeQualify(0x250,0x560,TRUE);
 ShowLine("start");               
 for(int i=0;i<=50;i++)
 {
 AbiGetTraceBuffer(0,0x1200,0x1200+100,
                          FrameQualify,
                         &(m_pTraceInfo[0]), &count, &readEnd);              
 if(count!=0) ShowLine("count");
 }
 ShowLine("end"); 

}                         
extern char* statusTbl[5];
             
void CListTrace::WildCardAddr(char *pszArgv)             
{
 
   ASSERT( pszArgv );
   
   CString  str;

    // Binary or Hexadecimal wildcard code.
    if ( 'B' == toupper(*(pszArgv+strlen(pszArgv)-1)) ) 
    {
     // Binary code.
     ASSERT ( 17 == strlen(pszArgv) );
    
     str = strupr(pszArgv);        
     if(str == "XXXXXXXXXXXXXXXXB")
     {
      FrameQualify.qlfyType[4] = 0;
      return;
      }
     FrameQualify.addr[1][0]=0x0ffff;
     FrameQualify.addr[0][0]=0;
     for ( int i = 0; i < 17-1; i++ ) 
      {
       if ( '0' != pszArgv[i] &&
         '1' != pszArgv[i] &&
         'X' != toupper(pszArgv[i]) ) ASSERT(0);
        
       if ('0'==pszArgv[i]) FrameQualify.addr[0][0] &= ~((WORD)1<<(15-i));
       if ('1'==pszArgv[i]) FrameQualify.addr[0][0] |= ((WORD)1<<(15-i));
       if ('X'==toupper(pszArgv[i])) FrameQualify.addr[1][0] &= ~((WORD)1<<(15-i));
       }
     FrameQualify.qlfyType[4] = 0x02;
     return ;
     }
    else 
    {
     // Hexidecimal code.
     ASSERT( 4 == strlen(pszArgv) ) ;
     str = strupr(pszArgv);        
     if(str == "XXXX")
      {
       FrameQualify.qlfyType[4] = 0;
       return;
       }
     int i = 4096;
     int j = 1;
     FrameQualify.addr[1][0] = 0x0ffff;
     FrameQualify.addr[0][0] = 0;
     char* p = pszArgv;
     while ( *p ) 
      {
        if ( isxdigit(*p) || 'X' == toupper(*p) ) 
        { 
        
         if(isdigit(*p)) 
          FrameQualify.addr[0][0] +=(WORD)(*p - '0')*i;
          else
          { 
           if(toupper(*p)>='A'&&toupper(*p)<='F')
           FrameQualify.addr[0][0] +=(WORD)(toupper(*p) - 'A'+10)*i;
           }
           
         if('X'==toupper(*p))
          {
            switch(j)
            {
            case 1:
                FrameQualify.addr[1][0] =0x0fff;
                break;
            case 2:
                FrameQualify.addr[1][0] &=0xf0ff;
                break;
            case 3:
                FrameQualify.addr[1][0] &=0xff0f;
                break;
            case 4:
                FrameQualify.addr[1][0] &=0x0fff0;
             }    //case
            }//if
        p++;
        j++;
        i =(int)i/16;
        }
        else 
        { ASSERT(0); }
      }//WHILE    
    FrameQualify.qlfyType[4] = 0x02;
    return ;  
    }//ELSE  
    return;
 }//FUNCTION
 
void CListTrace::WildCardData(char *pszArgv)             
{
 
   ASSERT( pszArgv );
   
   CString  str;

    // Binary or Hexadecimal wildcard code.
    if ( 'B' == toupper(*(pszArgv+strlen(pszArgv)-1)) ) 
    {
     // Binary code.
     ASSERT ( 9 == strlen(pszArgv) );
    
     str = strupr(pszArgv);        
     if(str == "XXXXXXXXB")
     {
      FrameQualify.qlfyType[6] = 0;
      return;
      }
     FrameQualify.data2=0x0ff;
     FrameQualify.data1=0;
     for ( int i = 0; i < 9-1; i++ ) 
      {
       if ( '0' != pszArgv[i] &&
         '1' != pszArgv[i] &&
         'X' != toupper(pszArgv[i]) ) ASSERT(0);
        
       if ('0'==pszArgv[i]) FrameQualify.data1 &= (WORD)~(1<<(7-i));
       if ('1'==pszArgv[i]) FrameQualify.data1 |= (WORD)(1<<(7-i));
       if ('X'==toupper(pszArgv[i])) FrameQualify.data2 &= (WORD)~(1<<(7-i));
       }
     FrameQualify.qlfyType[6] = 0x02;
     return ;
     }
    else 
    {
     // Hexidecimal code.
     ASSERT( 2 == strlen(pszArgv) ) ;
     str = strupr(pszArgv);        
     if(str == "XX")
      {
       FrameQualify.qlfyType[6] = 0;
       return;
       }
     int i = 16;
     int j = 1;  
     
     FrameQualify.data2 = 0x0ff;
     FrameQualify.data1 = 0;
     char *p=pszArgv;
     while ( *p ) 
      {
        if ( isxdigit(*p) || 'X' == toupper(*p) ) 
        { 
        
         if(isdigit(*p)) 
          FrameQualify.data1 +=(WORD)(*p - '0')*i;
          else
          { 
           if(toupper(*p)>='A'&&toupper(*p)<='F')
           FrameQualify.data1 +=(WORD)(toupper(*p) - 'A'+10)*i;
           }
           
         if('X'==toupper(*p))
          {
            switch(j)
            {
            case 1:
                FrameQualify.data2 =0x0f;
                break;
            case 2:
                FrameQualify.data2 &=0xf0;
                break;
             }    //case
            }//if
        p++;
        j++;
        i =(int)i/16;
        }
        else 
        { ASSERT(0); }
      FrameQualify.qlfyType[6] = 02;  
      }//WHILE
    }//ELSE  
    return;
 }//FUNCTION

void CListTrace::SetAddr(int* indexhere)
{       
  (*indexhere)++;
  ASSERT(*indexhere<ArgMax);
  
  //for range cmd
  if(IsKeyword(g_range, ArgPoint[*indexhere]))
   {
    FrameQualify.qlfyType[4] = 0x10;
    (*indexhere)++;
    ASSERT(*indexhere<ArgMax);
    if (IsPAddr(ArgPoint[*indexhere]))
    	FrameQualify.addr[0][0] = g_adr,
    	FrameQualify.addr[0][1]=g_adrSpace;
    (*indexhere)++;
    ASSERT(*indexhere<ArgMax);
    if (IsPAddr(ArgPoint[*indexhere]))
    {
	    if(g_adrSpace<FrameQualify.addr[0][1])
    	 	g_adrSpace=FrameQualify.addr[0][1];
    	FrameQualify.addr[1][0] = g_adr;
    	FrameQualify.addr[1][1]=g_adrSpace;
    }
    (*indexhere)++;
    FrameQualify.addrCount=2;
    }        
  else
  //for xaddr  
  if(IsWildCardAddr(ArgPoint[*indexhere]))
   {
    WildCardAddr(ArgPoint[*indexhere]);       
    (*indexhere)++;
    }
  else  
  //for maximum ten addresses
  if (IsPAddr(ArgPoint[*indexhere]))
   {                              
    int nums=0;                       
    FrameQualify.qlfyType[4] = 0x40;
    while(*indexhere<ArgMax  &&   nums<10 &&  
         IsPAddr(ArgPoint[*indexhere]))
     {
      if (IsPAddr(ArgPoint[*indexhere]))
      	FrameQualify.addr[nums][0] = g_adr,
      	FrameQualify.addr[nums][1]=g_adrSpace;
      (*indexhere)++;  nums++;
      FrameQualify.addrCount=(WORD)nums;
      
      }//while
    }//if
}//function

void CListTrace::SetData(int* indexhere)
{       
  
  char*   stop_at;
  
  (*indexhere)++;
  ASSERT(*indexhere<ArgMax);
  
  //for range cmd
  if(IsKeyword(g_range, ArgPoint[*indexhere]))
   {
    FrameQualify.qlfyType[6] = 0x10;
    (*indexhere)++;
    ASSERT(*indexhere<ArgMax);
    if (ISEVENTDATA(ArgPoint[*indexhere]))  
     FrameQualify.data1 = (WORD)strtoul(ArgPoint[*indexhere],&stop_at,16);
    (*indexhere)++;
    ASSERT(*indexhere<ArgMax);
    if (ISEVENTDATA(ArgPoint[*indexhere]))  
     FrameQualify.data2 = (WORD)strtoul(ArgPoint[*indexhere],&stop_at,16);
    (*indexhere)++;
    }        
  else
  //for xaddr  
  if(IsWildCardAddr(ArgPoint[*indexhere]))
   {
    WildCardData(ArgPoint[*indexhere]);       
    (*indexhere)++;
    }
  else  
  //for one addresses
  if ( ISEVENTDATA(ArgPoint[*indexhere]) ) 
   {                              
    FrameQualify.qlfyType[6] = 0x1;
    FrameQualify.data1 = (WORD)strtoul(ArgPoint[*indexhere],&stop_at,16);
    (*indexhere)++;  
    }//if
}//function

void CListTrace::SetStatus(int* indexhere)
{
  int result;
  
  (*indexhere)++;              
  ASSERT(*indexhere<ArgMax);
  FrameQualify.qlfyType[8] = 1;
  FrameQualify.status = 0;
  
  result=IsStatus(ArgPoint[*indexhere]);
  while(*indexhere<ArgMax && result>=0) 
   {
    FrameQualify.status = FrameQualify.status | (((ULONG)1)<<result);
    (*indexhere)++; 
    if(*indexhere>=ArgMax) break;
    result=IsStatus(ArgPoint[*indexhere]);
    }
  }  
                                       
void CListTrace::GetAbiFrame(WORD howMuch)
{
  WORD BeginNo,EndNo;
  WORD RecordStart;
  UCHAR count,readEnd; 
                                     
  AbiFrameNum=RecordFrameStart;                                   
  readEnd=1; count=0;  RecordStart=RecordFrameStart;
  if(BeginFrameNo>EndFrameNo) return ;
  BeginNo=BeginFrameNo;   
  if(howMuch==0)
   EndNo=(BeginNo+MAX_INST_LINE-RecordStart-1>EndFrameNo)
         ? EndFrameNo:BeginNo+MAX_INST_LINE-1-RecordStart;                  
   else                  
   { 
    if(howMuch+RecordStart>MAX_INST_LINE) howMuch =MAX_INST_LINE-RecordStart; 
    EndNo=(BeginNo+howMuch-1>EndFrameNo)
          ? EndFrameNo:BeginNo+howMuch-1;       
    }
  ShowReadTraceCurSite(BeginNo);
  //1 read not end  0 read end
  AbiGetTraceBuffer(readDirect,BeginNo,EndNo,FrameQualify,
                    &(m_pTraceInfo[RecordStart]),&count,&readEnd);
    
  AbiFrameNum+=(WORD)count; 
  ASSERT(AbiFrameNum<=MAX_INST_LINE);
  RecordStart+=(WORD)count;                      
          
  BeginFrameNo=EndNo+1;
  
  return;                    
 }                                      




//added by john 96.1 for 320
void CListTrace::GetAbiFrame320(WORD howMuch)
{
  WORD BeginNo,EndNo;
  WORD RecordStart;
  UCHAR count,readEnd,countTmp,countTmp2; 
  static WORD addrSave;
  static TRACE_INFO frameSave;
  static TRACE_INFO frameSave2;
  TRACE_INFO* infoSave;
  unsigned int iTmp,iTmp2,j,j2;
  
  countTmp = countTmp2 = 0;
  infoSave = (TRACE_INFO far*)GlobalAllocPtr(GMEM_MOVEABLE,
              sizeof(TRACE_INFO)*(MAX_INST_LINE+6));
  if(NULL==m_pTraceInfo)
   {
    ErrDisplayError(ER_EMU_INSUFFICIENT_MEMORY);
    ASSERT(0);
    }
                                     
  AbiFrameNum=RecordFrameStart;                                   
  readEnd=1; count=0;  RecordStart=RecordFrameStart;
  if(BeginFrameNo>EndFrameNo) return ;
  BeginNo=BeginFrameNo;   
  if(howMuch==0)
   EndNo=(BeginNo+MAX_INST_LINE-RecordStart-1>EndFrameNo)
         ? EndFrameNo:BeginNo+MAX_INST_LINE-1-RecordStart;                  
   else                  
   { 
    if(howMuch+RecordStart>MAX_INST_LINE) howMuch =MAX_INST_LINE-RecordStart; 
    EndNo=(BeginNo+howMuch-1>EndFrameNo)
          ? EndFrameNo:BeginNo+howMuch-1;       
    }
  
  ShowReadTraceCurSite(BeginNo);
  AbiGetTraceBuffer(readDirect,BeginNo,EndNo,FrameQualify,
                    &(m_pTraceInfo[RecordStart]),&count,&readEnd);
  if(count != 0)
  {
  //DETECT AK FOR 320                 
  WORD EndNoTmp,BeginNoTmp;
  static WORD addrSaveAK ; 
  static BOOL nextAK ;
  int preAKnum=0;
  if (sTatus320 == STATUS_NORMAL) nextAK = FALSE;
  if (nextAK) 
   { 
    if(m_pTraceInfo[0].addr == addrSaveAK)
     m_pTraceInfo[0].status = STATUS_AK;
    nextAK = FALSE; 
    }
  BeginNoTmp = EndNo+1 > m_lastFrameNo ? EndNo : EndNo+1;
  EndNoTmp = EndNo+2 > m_lastFrameNo ? m_lastFrameNo : EndNo+2;
  countTmp = 0;
  if (BeginNoTmp == EndNo)
   {      
    ShowReadTraceCurSite(BeginNoTmp);
    AbiGetTraceBuffer(readDirect,BeginNoTmp,EndNoTmp,FrameQualify,
                      &(infoSave[0]),&countTmp,&readEnd);
    for ( iTmp = 1; iTmp <= countTmp; iTmp++)  
      switch (preAKnum)
       {
        case 0 : 
             if ((infoSave[countTmp-iTmp].status&0x07) == STATUS_AK)
              { 
               preAKnum = 2;
               addrSave = infoSave[countTmp-iTmp].addr;
               }
             break;
        case 2 : 
             if (infoSave[countTmp-iTmp].addr == addrSave)       
              { 
               preAKnum = 1;
               infoSave[countTmp-iTmp].status = STATUS_AK;               
               }
               else preAKnum = 0;
              break;
        case 1 :          
             if (infoSave[countTmp-iTmp].addr == addrSave)       
              { 
               if ((infoSave[countTmp-iTmp].status&0x07) == STATUS_S)
                {     
                 preAKnum = -1; //maybe this is the first status_s 
                 }
                 else 
                  {
                   infoSave[countTmp-iTmp].status = STATUS_AK;               
                   preAKnum = 0;
                   }
               }
               else preAKnum = 0;
             break; 
        case -1 :   
             preAKnum = 0 ;
             break;       
        default : ASSERT(0); break;     
        } //SWITCH
    }    //IF
  
  for ( iTmp = 1; iTmp <= count; iTmp++)  
      switch (preAKnum)
       {
        case 0 : 
             if ((m_pTraceInfo[count-iTmp].status&0x07) == STATUS_AK)
              { 
               preAKnum = 2;
               addrSave = m_pTraceInfo[count-iTmp].addr;
               if (iTmp!=1)
                { 
                 if(m_pTraceInfo[count-iTmp].addr == addrSave)
                  m_pTraceInfo[count-iTmp+1].addr = STATUS_AK;                 
                 }
                 else
                  { 
                   addrSaveAK = addrSave; 
                   nextAK = TRUE;
                   }
               }
             break;
        case 2 : 
             if ((m_pTraceInfo[count-iTmp].status&0x07) == STATUS_S
                 && infoSave[count-iTmp].addr == addrSave)       
              { 
               preAKnum = 1;
               m_pTraceInfo[count-iTmp].status = STATUS_AK;               
               }
               else preAKnum = 0;
              break;
        case 1 :           
             if (m_pTraceInfo[count-iTmp].addr == addrSave)       
              { 
               if ((m_pTraceInfo[count-iTmp].status&0x07) == STATUS_S)
                {     
                 preAKnum = -1; //maybe this is the first status_s 
                 }
                 else 
                  {
                   m_pTraceInfo[count-iTmp].status = STATUS_AK;               
                   preAKnum = 0;
                   }
               }
               else preAKnum = 0;
             break; 
        case -1 : 
             if (iTmp!=1 
                 && (m_pTraceInfo[count-iTmp].status&0x07) == STATUS_S
                 && m_pTraceInfo[count-iTmp].addr == addrSave)
              m_pTraceInfo[count-iTmp+1].status = STATUS_AK;
             preAKnum = 0;
             break;
        default : ASSERT(0); break;
               
              
        }  
    
  //MODIFY TRACE BUFFER FOR 320
  for ( unsigned int i=RecordStart; i<RecordStart+count;i++)
   switch (sTatus320)
    {
     case STATUS_NORMAL :
          iTmp = 0;
          countTmp = 0;
          
          if (BeginNo == 0)  
           {
            i--;
            sTatus320 = STATUS_NORMAL_FOLLOW;
            break;
            }
          
          while (iTmp<4 && iTmp<RecordStart+count)
           {       
            if((m_pTraceInfo[iTmp].status&0x07) == STATUS_S) break;
            iTmp++;
            }
          
          if (iTmp == 4 || iTmp == RecordStart+count || BeginNo == 0)  
           {
            i--;
            sTatus320 = STATUS_NORMAL_FOLLOW;
            break;
            }
          
          i=iTmp;
          iTmp2 = BeginNo-(4-iTmp);
          if ( iTmp2 <0) iTmp2 = 0;         
          
          ShowReadTraceCurSite(BeginNo);
          AbiGetTraceBuffer(readDirect,iTmp2,BeginNo-1,FrameQualify,
                    &(infoSave[0]),&countTmp,&readEnd);
                    
          for (j=1;j<=countTmp;j++) 
           {
            
            if ((infoSave[countTmp-j].status&0x07)==STATUS_F)
             {
              if (iTmp==0 && j==1 
                  && infoSave[countTmp-j].addr == m_pTraceInfo[i].addr
                  && infoSave[countTmp-j].data == m_pTraceInfo[i].data)      
               { 
                //to check if last frame is prefetch
                //BOOL secondPrefetch=FALSE;
                for (j2=2;j2<=countTmp;j2++)
                 { 
                  if ((infoSave[countTmp-j2].status&0x07)==STATUS_S)
                   {
                    if ( infoSave[countTmp-j2].addr == infoSave[countTmp-j].addr-1
                         && (infoSave[countTmp-j2].data&0xef)==0x83)                  
                     {    
                      infoSave[countTmp-j].status = STATUS_S_F;//GIVE STATUS_S_F TO AVOID DOUBLE ASM
                      addrSave = infoSave[countTmp-j2].addr;
                      memcpy(&frameSave,&(infoSave[countTmp-j]),sizeof(TRACE_INFO));
                      //infoSave[countTmp-j].status = STATUS_F;
                      sTatus320=STATUS_MOVC_GET_FETCH1;        
                      i--;
                      }    
                    break;
                    }
                  }
                if (sTatus320==STATUS_MOVC_GET_FETCH1)  break;
                }
               } 
                    
            if ((infoSave[countTmp-j].status&0x07)==STATUS_S)
             {
              if (iTmp==0 && j==1 
                  && infoSave[countTmp-j].addr == m_pTraceInfo[i].addr
                  && infoSave[countTmp-j].data == m_pTraceInfo[i].data)      
               { 
                //to check if last frame is prefetch
                //BOOL secondPrefetch=FALSE;
                for (j2=2;j2<=countTmp;j2++)
                 { 
                  if ((infoSave[countTmp-j2].status&0x07)==STATUS_S)
                   {
                    if ( infoSave[countTmp-j2].addr == infoSave[countTmp-j].addr-1
                         && (infoSave[countTmp-j2].data&0xef)==0x83)                  
                     {    
                      infoSave[countTmp-j].status = STATUS_S_F;//GIVE STATUS_S_F TO AVOID DOUBLE ASM
                      addrSave = infoSave[countTmp-j2].addr;
                      memcpy(&frameSave,&(infoSave[countTmp-j]),sizeof(TRACE_INFO));
                      //infoSave[countTmp-j].status = STATUS_F;
                      sTatus320=STATUS_MOVC_GET_FETCH1;        
                      i--;
                      }    
                    break;
                    }
                  }
                if (sTatus320==STATUS_MOVC_GET_FETCH1)  break;
                }
                
              if ( infoSave[countTmp-j].addr == m_pTraceInfo[i].addr-1
                   && (infoSave[countTmp-j].data&0xef)==0x83)
               {                            
                addrSave = infoSave[countTmp-j].addr;
                sTatus320=STATUS_MOVC;
                i--;
                }
              break;    
              }
            } 
            
          if (sTatus320!=STATUS_MOVC && sTatus320!=STATUS_MOVC_GET_FETCH1)  
           {
            i--;   
            sTatus320 = STATUS_NORMAL_FOLLOW;
            }
          break; 
          
          
     case STATUS_NORMAL_FOLLOW  :
          
          if ( (m_pTraceInfo[i].data&0xef)==0x83
               && ( (m_pTraceInfo[i].status&0x07) == STATUS_S 
                    || (m_pTraceInfo[i].status&0x07) == STATUS_S_F ) )    
           {  
            addrSave = m_pTraceInfo[i].addr;
            sTatus320 = STATUS_MOVC;
            }
          if ( (m_pTraceInfo[i].status&0x07) == STATUS_S_F )
           m_pTraceInfo[i].status = STATUS_F;      
          break;
          
     case STATUS_MOVC :
          if ( (m_pTraceInfo[i].status&0x07) == STATUS_S 
               /*|| (m_pTraceInfo[i].status&0x07) == STATUS_AK*/)
           if ( m_pTraceInfo[i].addr == addrSave+1 )
            { 
             memcpy(&frameSave,&(m_pTraceInfo[i]),sizeof(TRACE_INFO));
             m_pTraceInfo[i].status = STATUS_F;
             sTatus320 = STATUS_MOVC_GET_FETCH1;
             break;
             }
          sTatus320 = STATUS_NORMAL_FOLLOW;                           
          if ( (m_pTraceInfo[i].status&0x07) == STATUS_S ) i--;
          break;
          
     case STATUS_MOVC_GET_FETCH1 :  
          if ( (m_pTraceInfo[i].status&0x07) == STATUS_F
               /*|| (m_pTraceInfo[i].status&0x07) == STATUS_AK */
               || (m_pTraceInfo[i].status&0x07) == STATUS_S)
           if ( m_pTraceInfo[i].addr == addrSave+1 )
            {                                  
             m_pTraceInfo[i].status = STATUS_F;
             sTatus320 = STATUS_MOVC_GET_FETCH2;
             break;
             }                                 
          if (i != 0) 
           {                                      
            //ASSERT(frameSave.status == STATUS_S);
            memcpy(&(m_pTraceInfo[i-1]),&frameSave,sizeof(TRACE_INFO));
            i-=2;
            sTatus320 = STATUS_NORMAL_FOLLOW;   
            break;
            }
            else
             { 
              //ASSERT(frameSave.status == STATUS_S);
              memcpy(&(infoSave[0]),&frameSave,sizeof(TRACE_INFO));
              memcpy(&(infoSave[1]),&(m_pTraceInfo[0]),
                     (RecordStart+count)*sizeof(TRACE_INFO));
              count++; 
              memcpy(&(m_pTraceInfo[0]),&(infoSave[0]),
                     (RecordStart+count)*sizeof(TRACE_INFO));       
              i--;       
              sTatus320 = STATUS_NORMAL_FOLLOW;   
              break;
              }
             
          break;
          
     case STATUS_MOVC_GET_FETCH2 :
          if ( (m_pTraceInfo[i].status&0x07) == STATUS_F 
               /*|| (m_pTraceInfo[i].status&0x07) == STATUS_AK */)
           {
           if ( m_pTraceInfo[i].addr != addrSave+2 )
            {                             
             //ASSERT(frameSave.status == STATUS_S);
             memcpy(&(m_pTraceInfo[i]),&frameSave,sizeof(TRACE_INFO));
             sTatus320 = STATUS_NORMAL_FOLLOW;   
             i--;
             break;
             }
             else
              { 
               memcpy(&frameSave2,&(m_pTraceInfo[i]),sizeof(TRACE_INFO));
               sTatus320 = STATUS_MOVC_GET_FETCH3;
               break;
               }                                 
            }   
            
          //change last frame ,if this is the first frame,add a new frame   
          if (i != 0) 
           {                                      
            //ASSERT(frameSave.status == STATUS_S);
            memcpy(&(m_pTraceInfo[i-1]),&frameSave,sizeof(TRACE_INFO));
            i-=2;
            sTatus320 = STATUS_NORMAL_FOLLOW;   
            break;
            }
            else
             { 
              //ASSERT(frameSave.status == STATUS_S);
              memcpy(&(infoSave[0]),&frameSave,sizeof(TRACE_INFO));
              memcpy(&(infoSave[1]),&(m_pTraceInfo[0]),
                     (RecordStart+count)*sizeof(TRACE_INFO));
              count++;
              memcpy(&(m_pTraceInfo[0]),&(infoSave[0]),
                     (RecordStart+count)*sizeof(TRACE_INFO));       
              i--; 
              sTatus320 = STATUS_NORMAL_FOLLOW;   
              break;
              }
          
          break;                  
     
     case STATUS_MOVC_GET_FETCH3 :     
          if ( (m_pTraceInfo[i].status&0x07) == STATUS_F 
               /*|| (m_pTraceInfo[i].status&0x07) == STATUS_AK*/ )
           if ( m_pTraceInfo[i].addr == addrSave+2 )
            {                             
             if (i != 0) 
              {                                      
               //ASSERT(frameSave.status == STATUS_S);
               memcpy(&(m_pTraceInfo[i-1]),&frameSave,sizeof(TRACE_INFO));
               i-=2;
               sTatus320 = STATUS_NORMAL_FOLLOW;   
               break;
               }
               else
                { 
                 //ASSERT(frameSave.status == STATUS_S);
                 memcpy(&(infoSave[0]),&frameSave,sizeof(TRACE_INFO));
                 memcpy(&(infoSave[1]),&(m_pTraceInfo[0]),
                        (RecordStart+count)*sizeof(TRACE_INFO));
                 count++;
                 memcpy(&(m_pTraceInfo[0]),&(infoSave[0]),
                        (RecordStart+count)*sizeof(TRACE_INFO));       
                 i--;       
                 sTatus320 = STATUS_NORMAL_FOLLOW;   
                 break;
                 }
             break;
             }
             
          //change last frame ,if this is the first frame,add a new frame   
          if (i >1 ) //at least 2 frames
           {                                      
            //ASSERT(frameSave.status == STATUS_S);
            memcpy(&(m_pTraceInfo[i-2]),&frameSave,sizeof(TRACE_INFO));
            i-=3;
            sTatus320 = STATUS_NORMAL_FOLLOW;   
            break;
            }
            else
             { 
              if (i>0) //1 frame
               {
                //ASSERT(frameSave.status == STATUS_S);
                memcpy(&(infoSave[0]),&frameSave,sizeof(TRACE_INFO));
                memcpy(&(infoSave[1]),&(m_pTraceInfo[0]),
                       (RecordStart+count)*sizeof(TRACE_INFO));
                count++;
                memcpy(&(m_pTraceInfo[0]),&(infoSave[0]),
                       (RecordStart+count)*sizeof(TRACE_INFO));       
                i-=2;       
                sTatus320 = STATUS_NORMAL_FOLLOW;   
                break;
                }
                else // 0 frame
                 {      
                  //ASSERT(frameSave.status == STATUS_S);
                  memcpy(&(infoSave[0]),&frameSave,sizeof(TRACE_INFO));
                  memcpy(&(infoSave[1]),&frameSave2,sizeof(TRACE_INFO));                  
                  memcpy(&(infoSave[2]),&(m_pTraceInfo[0]),
                         (RecordStart+count)*sizeof(TRACE_INFO));
                  count+=2;
                  memcpy(&(m_pTraceInfo[0]),&(infoSave[0]),
                         (RecordStart+count)*sizeof(TRACE_INFO));       
                  i--;       
                  sTatus320 = STATUS_NORMAL_FOLLOW;   
                  break;
                  }   
              break;    
              }
          break;
          
     default : 
          ASSERT(0);     
          break;
     }
  }//if count != 0
  
  AbiFrameNum+=(WORD)count; 
  ASSERT(AbiFrameNum<=MAX_INST_LINE+1);
  RecordStart+=(WORD)count;                      
          
  BeginFrameNo=EndNo+1;
  
  if(NULL!=infoSave)
    GlobalFreePtr(infoSave);
  return;                    
 }                                      

                 
BOOL CListTrace::GetAsmStr(WORD *FramePoint,unsigned char *AsmResult)
{
  unsigned char AsmInstrLen;
  unsigned char AsmCode[20],CodePoint;
  unsigned short AsmAddr;
  BOOL CanBeAsm,isAK=FALSE;
  
  ASSERT((m_pTraceInfo[*FramePoint].status&0x7)==STATUS_S);
  
  isAK=FALSE;      
  AsmResult[0]=0; CodePoint=0; CanBeAsm=TRUE;
  AsmAddr=(unsigned short)(m_pTraceInfo[*FramePoint].addr);
        
  AsmInstrLen=TRCGetInstLen(m_pTraceInfo[*FramePoint].data);       
  
  ASSERT(AsmInstrLen<4);
  AsmCode[CodePoint]=m_pTraceInfo[*FramePoint].data; 
  (*FramePoint)++; CodePoint++;
  
  WORD i;
  for(i=0; i<(WORD)AsmInstrLen-1 && (*FramePoint)<AbiFrameNum ; i++)
   {
    if((m_pTraceInfo[*FramePoint].status&0x7)==STATUS_AK) 
     { isAK=TRUE; break; }
    if(m_pTraceInfo[*FramePoint].addr!=(WORD)(AsmAddr+i+1)) break;
    if((m_pTraceInfo[*FramePoint].status&0x7)==STATUS_S) break;
    AsmCode[CodePoint]=m_pTraceInfo[*FramePoint].data;
    CodePoint++;(*FramePoint)++;
    }//while
    
  if (isAK) 
   {
    
    AsmResult[0]=0;
    CodeHextoText((char *)AsmCode,(char *)AsmResult,CodePoint);//insert obj code
    strcat((char *)AsmResult,"INTERRUPTION");    
    return FALSE;
    
    }
    
  if(CodePoint<AsmInstrLen && *FramePoint>=AbiFrameNum && BeginFrameNo<=EndFrameNo) 
   return NEED_MORE_FRAME;
   
  if(CodePoint==AsmInstrLen) CanBeAsm=TRUE; else CanBeAsm=FALSE;
                                                           
  //added by john 96.8 to fix the status_ak bug                                                           
  if(CanBeAsm==TRUE) 
   if(TRCGetInst(AsmAddr,AsmCode,AsmInstrLen,AsmResult)==0){
   	if ((1 == AsmInstrLen) && (*FramePoint<AbiFrameNum) &&
   		((m_pTraceInfo[*FramePoint].status&0x7)==STATUS_AK) &&
   		(m_pTraceInfo[*FramePoint].addr == (m_pTraceInfo[(*FramePoint)-1].addr))&&
   		(m_pTraceInfo[*FramePoint].data == (m_pTraceInfo[(*FramePoint)-1].data))  ){
   		AsmResult[0]=0;
	    CodeHextoText((char *)AsmCode,(char *)AsmResult,CodePoint);//insert obj code
	    strcat((char *)AsmResult,"INTERRUPTION");    
	    (*FramePoint)++;
	    return FALSE;
   	}	
    return TRUE;
   } 
  AsmResult[0]=0;
  CodeHextoText((char *)AsmCode,(char *)AsmResult,CodePoint);//insert obj code
  strcat((char *)AsmResult,"    ?");    
  return FALSE;
    
 }               

/* 
BOOL CListTrace::GetCStrNum(WORD *FramePoint,WORD *NextAddr,U16* line , U32* module ) 
{ 
  U16 linenum;
  U32 moduleDesc;
  U32 startAddr , endAddr;
  int bank=1;
  
  //skip no use frame  
  //while(SrcAddr2LinenumStart((U32)(m_pTraceInfo[*FramePoint].addr),
    //                   linenum , moduleDesc)!=0)
   //{                 
    //(*FramePoint)++;               
    //if(*FramePoint>=AbiFrameNum) return GET_NOTHING_END;
    //}                                                   
  if((U32)(m_pTraceInfo[*FramePoint].status&0x7)!=STATUS_S)
   AfxMessageBox("Is HW ok !!!"); 
  if(SrcAddr2LinenumStart((U32)(m_pTraceInfo[*FramePoint].addr),
                          linenum , moduleDesc)!=0 )
  {                  
   //unsigned short usB,usE;
   //if(GetLibRange( (unsigned short)(m_pTraceInfo[*FramePoint].addr),
   //                usB,usE) == 0 )     
   //SetExcludeQualify(usB,usE,TRUE);               
   (*FramePoint)++;  return GET_NOTHING; 
   }                       
  
  if(SrcLinenum2Range(moduleDesc,linenum,startAddr,endAddr, bank)!=0)
   { (*FramePoint)++;  return GET_NOTHING; }                  
  //this line is marked in 95.8 because Mr Gates said there are many statement
  //in one line source and he only do with the statement concept
  //ASSERT((U32)(m_pTraceInfo[*FramePoint].addr)==startAddr); 
   
  *NextAddr=(WORD)endAddr+1;
  *line=(WORD)linenum;
  *module=moduleDesc;                
  //added 95.10.11 to fasten the list source
  //if (isSource) SetExcludeQualify(startAddr,endAddr,FALSE);
  return GET_C_OK;

 }              
*/
 
//used to make the listing source quickly
void CListTrace::SetExcludeQualify(WORD ulBegin,WORD ulEnd,BOOL exClude)
{                                                                      
 if (exClude)                    
  {
   FrameQualify.addr[0][0] = ulBegin;
   FrameQualify.addr[1][0] = ulEnd;
   FrameQualify.qlfyType[4] = 0x20;
   }
   else
   { 
    FrameQualify.qlfyType[4] = 0;
    }
 }         
//list trace data in shell                  
void CListTrace::ListTrcDataToShell()
{ 
                         
  if((BeginFrameNo>EndFrameNo) || (EndFrameNo>m_lastFrameNo)) 
   {                  
    char strTmp[40];                                  
    wsprintf(strTmp,"The last frame Number is %04X.",m_lastFrameNo);
    ShowLine(strTmp);
    return;
    }             
    
  
  readDirect=NULL;  RecordFrameStart=0;
  AbiFrameNum=0;
  
  wsprintf(strTmpShow,"FRAME    ADDR    DATA    STATUS    PORT%d   SPARE ", g_nPort);
  ShowLine(strTmpShow);
  
  while(BeginFrameNo<=EndFrameNo)
   {
     if(TestKey(VK_ESCAPE)) return;
     GetAbiFrame();
    
     for (unsigned int i = 0;i<AbiFrameNum;i++)
      {
        if(TestKey(VK_ESCAPE))
        return;
        
        unsigned char spare = (unsigned char)(m_pTraceInfo[i].status&0xf8);
        unsigned char status =(unsigned char)(m_pTraceInfo[i].status&0x7);
        CString strBit = "";
        
        for(int j=7;j>2;j--)
        {
        if((spare&(1<<j)) !=0)
            strBit += '1';
        else
            strBit += '0';
        }            
        
        if(g_nBankNum)
        {
        	if(status==2||status==3)
        		wsprintf(strTmpShow," %04X     X:%04X %02X      %2s        %02X      %5s",
                	 m_pTraceInfo[i].frameNo, m_pTraceInfo[i].addr,
                 	m_pTraceInfo[i].data,
                 	statusTbl[status],m_pTraceInfo[i].port,strBit);
        	else
        		wsprintf(strTmpShow," %04X    P%d:%04X %02X      %2s        %02X      %5s",
                	 m_pTraceInfo[i].frameNo,GetSpace(m_pTraceInfo[i].port)-6, m_pTraceInfo[i].addr,
                 	m_pTraceInfo[i].data,
                 	statusTbl[status],m_pTraceInfo[i].port,strBit);
        }
        else
        	wsprintf(strTmpShow," %04X    %04X    %02X      %2s        %02X      %5s",
                 m_pTraceInfo[i].frameNo,m_pTraceInfo[i].addr,
                 m_pTraceInfo[i].data,
                 statusTbl[status],m_pTraceInfo[i].port,strBit);
        ShowLine(strTmpShow); 
      }
   }//while  
     
  }                                  
       
                          
//list trace instraction in shell                          
void CListTrace::ListTrcAsmToShell()       
{ 
                  
  if((BeginFrameNo>EndFrameNo) || (EndFrameNo>m_lastFrameNo)) 
   {
    wsprintf(strTmpShow,"The last frame Number is %04X.",m_lastFrameNo);
    ShowLine(strTmpShow);
    return;
    }
  
  //ONLY STATUS_S STATUS_F STATUS_AK IS USEFUL     
  DWORD tmpStatus;  
  if(GetCpuId() != 50 /*not cpu 320*/)
   {
    if(FrameQualify.qlfyType[8] == 1)
     {
      if((FrameQualify.status&(((ULONG)1)<<STATUS_S))!=(((ULONG)1)<<STATUS_S) )
       return ;
      tmpStatus = FrameQualify.status; 
      FrameQualify.status = 0;
      FrameQualify.status = FrameQualify.status | (((ULONG)1)<<STATUS_S);
      if((tmpStatus&(((ULONG)1)<<STATUS_F))==(((ULONG)1)<<STATUS_F))
      FrameQualify.status = FrameQualify.status | (((ULONG)1)<<STATUS_F); 
      if((tmpStatus&(((ULONG)1)<<STATUS_AK))==(((ULONG)1)<<STATUS_AK))
      FrameQualify.status = FrameQualify.status | (((ULONG)1)<<STATUS_AK); 
      }   
      else
       { 
        FrameQualify.qlfyType[8] = 1;
        FrameQualify.status = 0;
        FrameQualify.status = FrameQualify.status | (((ULONG)1)<<STATUS_S);
        FrameQualify.status = FrameQualify.status | (((ULONG)1)<<STATUS_F);
        FrameQualify.status = FrameQualify.status | (((ULONG)1)<<STATUS_AK);
        }
     
    GetFrame = CListTrace::GetAbiFrame; 
    }
    else//for 320
     { 
      if(FrameQualify.qlfyType[8] == 1)
      {
       if((FrameQualify.status&(((ULONG)1)<<STATUS_S))!=(((ULONG)1)<<STATUS_S) )
        return ;
       }
      FrameQualify.qlfyType[8] = 1;
      FrameQualify.status = 0;
      FrameQualify.status = FrameQualify.status | (((ULONG)1)<<STATUS_S)
                                                | (((ULONG)1)<<STATUS_F)
                                                | (((ULONG)1)<<STATUS_AK);
                                                
      GetFrame = CListTrace::GetAbiFrame320;                                            
      sTatus320 = STATUS_NORMAL;//added by john 96.1 for 320
      
      }                                         
      
  readDirect=NULL;  RecordFrameStart=0;
  AbiFrameNum=0;
  
  ShowLine(" FRAME  ADDRESS  OBJECT    SOURCE"); 
  
  while(BeginFrameNo<=EndFrameNo)
   {
     WORD FramePoint;
     
     if(TestKey(VK_ESCAPE)) return;     
     (this->*GetFrame)();
     
     FramePoint=0; 
           
     while(FramePoint<AbiFrameNum)
      {              
        WORD FramePointTmp;
        
        if(TestKey(VK_ESCAPE)) return;
        
        //  skip frame until fetch cycle 
        while((FramePoint<AbiFrameNum) &&
              ((m_pTraceInfo[FramePoint].status&0x7)!=STATUS_S)
              ) FramePoint++;
        if(FramePoint>=AbiFrameNum) break;
              
        FramePointTmp=FramePoint;      
        
        BOOL ReturnValue=GetAsmStr(&FramePoint,(unsigned char *)strTmpTmp);
        //if the last operation's failue is the reason that there are more frame left(which is useful)
        if(ReturnValue==NEED_MORE_FRAME)
         {
          RecordFrameStart=0;
          while(FramePointTmp<AbiFrameNum)
           {
            memcpy(&(m_pTraceInfo[RecordFrameStart]),
                   &(m_pTraceInfo[FramePointTmp]),
                   sizeof(TRACE_INFO));
            FramePointTmp++;RecordFrameStart++;
            FramePoint=FramePointTmp;
            }
          }
          else
          {
           if(g_nBankNum)
           		wsprintf(strTmpShow," %04X   P%d:%04X  %s",
                    m_pTraceInfo[FramePointTmp].frameNo,GetSpace(m_pTraceInfo[FramePointTmp].port)-6, 
                    m_pTraceInfo[FramePointTmp].addr,strTmpTmp);
           else
           		wsprintf(strTmpShow," %04X   %04X     %s",
                    m_pTraceInfo[FramePointTmp].frameNo,
                    m_pTraceInfo[FramePointTmp].addr,strTmpTmp);
           ShowLine(strTmpShow);                                    
           RecordFrameStart=0;
           }
        
        
        }        
     }
  
 }//end                                             
                                 
//list trace c in shell
//use data from ctrcbuf
void CListTrace::ListTrcCToShell()
{
CString msg;
BOOL bRet=TRUE;
WORD beginframe=BeginFrameNo, endframe, count;
FrameC	frameC[10];
char    result[300];
int i;

	//check whether C is loaded
	if(0 != SrcIsLoaded())
	{
		ErrGetErrorText(ER_TRCSVR_LOADSRC, msg);
		ShowLine(msg.GetBuffer(msg.GetLength()));
		msg.ReleaseBuffer();
		return;
	}
	         
	if((BeginFrameNo>EndFrameNo) || (EndFrameNo>m_lastFrameNo)) 
	{                  
		wsprintf(strTmpTmp,"The last frame Number is %04X.",m_lastFrameNo);
		ShowLine(strTmpTmp);
		return;
	}
	ShowLine(" FRAME    LINE    SOURCE ");
    count=10;
	while(bRet&&!TestKey(VK_ESCAPE)&&count==10)
	{
		bRet=ListTrcCToWnd(0, &beginframe, &endframe, &count, frameC);
		if(count&&bRet)
			beginframe=frameC[count-1].phisicalNo+1;
		for(i=0; WORD(i)<count; i++)
		{
			wsprintf(result, " %s   %s    %s",
						frameC[i].frameNo, frameC[i].line,
						frameC[i].c);
			ShowLine(result);
		}
	}
}
  
     

//list trace mixed in shell
void CListTrace::ListTrcMixToShell()
{                   
CString msg;
BOOL bRet=TRUE;
WORD beginframe=BeginFrameNo, endframe, count;
FrameC	frameC[34];
char    result[300];
int i;

	//check whether C is loaded
	if(0 != SrcIsLoaded())
	{
		ErrGetErrorText(ER_TRCSVR_LOADSRC, msg);
		ShowLine(msg.GetBuffer(msg.GetLength()));
		msg.ReleaseBuffer();
		return;
	}
	         
	if((BeginFrameNo>EndFrameNo) || (EndFrameNo>m_lastFrameNo)) 
	{                  
		wsprintf(strTmpShow,"The last frame Number is %04X.",m_lastFrameNo);
		ShowLine(strTmpShow);
		return;
	}
	ShowLine(" FRAME    ADDRESS    OBJECT    SOURCE_CODE"); 
	count=10;
	while(bRet&&!TestKey(VK_ESCAPE)&&count==10)
	{
		bRet=ListTrcMixedToWnd(0, &beginframe, &endframe, &count, frameC);
		if(count&&bRet)
			beginframe=frameC[count-1].phisicalNo+1;
		for(i=0; WORD(i)<count; i++)
		{
			wsprintf(result, " %s   %s    %s",
						frameC[i].frameNo, frameC[i].line,
						frameC[i].c);
			ShowLine(result);
		}
	}
}//function

int CListTrace::GetSpace(UCHAR port)
{
int bank;

	bank=StkNumConvertToBank(int(port));
	if(bank==-1)
		return 1;
	else
		return 5+bank;
}

//list trace module in shell                           
void CListTrace::ListTrcModuleToShell()
{
	CString msg;
	U32 moduleDesc,modStart,modEnd,funcDesc,funcStart,funcEnd;
  
  //check whether C is loaded
	if(0 != SrcIsLoaded())
	{
		ErrGetErrorText(ER_TRCSVR_LOADSRC, msg);
		ShowLine(msg.GetBuffer(msg.GetLength()));
    	msg.ReleaseBuffer();
		return;
    }
    
  if((BeginFrameNo>EndFrameNo) || (EndFrameNo>m_lastFrameNo)) 
   {                  
    wsprintf(strTmpShow,"The last frame Number is %04X.",m_lastFrameNo);
    ShowLine(strTmpShow);
    return;
    }
  
  readDirect=NULL;  RecordFrameStart=0;
  AbiFrameNum=0;
  
  ShowLine(" FRAME  ADDRESS");
  
  //only status s f is useful
  if(GetCpuId() != 50 /*not cpu 320*/)
   {
    if(FrameQualify.qlfyType[8] == 1)
     {
      if((FrameQualify.status&(((ULONG)1)<<STATUS_S))!=(((ULONG)1)<<STATUS_S) )
       return ;
      }
    FrameQualify.qlfyType[8] = 1;
    FrameQualify.status = 0;
    FrameQualify.status = FrameQualify.status | (((ULONG)1)<<STATUS_S);
    
    GetFrame = CListTrace::GetAbiFrame; 
    }
    else//for 320
     { 
      if(FrameQualify.qlfyType[8] == 1)
      {
       if((FrameQualify.status&(((ULONG)1)<<STATUS_S))!=(((ULONG)1)<<STATUS_S) )
        return ;
       }
      FrameQualify.qlfyType[8] = 1;
      FrameQualify.status = 0;
      FrameQualify.status = FrameQualify.status | (((ULONG)1)<<STATUS_S)
                                                | (((ULONG)1)<<STATUS_F)
                                                /*| (((ULONG)1)<<STATUS_AK)*/;
                                                
      GetFrame = CListTrace::GetAbiFrame320;                                                
      sTatus320 = STATUS_NORMAL;//added by john 96.1 for 320
      
      }
  
  while(BeginFrameNo<=EndFrameNo)
   {
     WORD FramePoint;
     BOOL hasFunction,hasModule;
     hasFunction=hasModule=TRUE;
                                   
     if(TestKey(VK_ESCAPE)) return;
     (this->*GetFrame)();
     
     FramePoint=0; 
           
     while(FramePoint<AbiFrameNum)
      {              
        
        if(TestKey(VK_ESCAPE)) return;
        //module enter
        if(LstAddr2Info(GetSpace(m_pTraceInfo[FramePoint].port), (U16)(m_pTraceInfo[FramePoint].addr),moduleDesc,modStart,modEnd,
                        funcDesc,funcStart,funcEnd)!=0)
         {
          moduleDesc=0; 
          modStart=modEnd=(U32) (m_pTraceInfo[FramePoint].addr);
          }                                    
        if ( (modStart>(U32)(m_pTraceInfo[FramePoint].addr))||
             (modEnd<(U32)(m_pTraceInfo[FramePoint].addr)) ) 
         {
          moduleDesc=0; 
          modStart=modEnd=(U32) (m_pTraceInfo[FramePoint].addr);
          }                                    
          
        if(moduleDesc==0 || 0!= LstGetSymbolName((LPSTR)strTmpTmp,moduleDesc))  
         {
          wsprintf(strTmpShow," %04X   %04X   No Module information",
                    m_pTraceInfo[FramePoint].frameNo,
                    m_pTraceInfo[FramePoint].addr);
          if(hasModule)          
           { ShowLine(strTmpShow); hasModule=FALSE; }
          }
          else
          { 
           wsprintf(strTmpShow," %04X   %04X   Module Enter: %s",
                     m_pTraceInfo[FramePoint].frameNo,
                     m_pTraceInfo[FramePoint].addr,strTmpTmp);
           ShowLine(strTmpShow); hasModule=TRUE;  hasFunction=TRUE;
           }
        //in module  
        while(
              m_pTraceInfo[FramePoint].addr>=modStart &&
              m_pTraceInfo[FramePoint].addr<=modEnd) 
         {
          if(TestKey(VK_ESCAPE)) return;
          //funtion enter
          if(LstAddr2Info(GetSpace(m_pTraceInfo[FramePoint].port),
          			(U16)(m_pTraceInfo[FramePoint].addr),moduleDesc,modStart,
          			modEnd, funcDesc,funcStart,funcEnd)!=0 || funcDesc==0)
           {
            funcDesc=0; 
            funcStart=funcEnd=(U32) (m_pTraceInfo[FramePoint].addr);
            } 
          if ( (modStart>(U32)(m_pTraceInfo[FramePoint].addr))||
             (modEnd<(U32)(m_pTraceInfo[FramePoint].addr)) ) 
           {
            moduleDesc=0; 
            modStart=modEnd=(U32) (m_pTraceInfo[FramePoint].addr);
            }        
          if ( (funcStart>(U32)(m_pTraceInfo[FramePoint].addr))||
               (funcEnd<(U32)(m_pTraceInfo[FramePoint].addr)) ) 
           {
            funcDesc=0; 
            funcStart=funcEnd=(U32) (m_pTraceInfo[FramePoint].addr);
            }        
          
          if(funcDesc==0 || 0!= LstGetSymbolName((LPSTR)strTmpTmp ,funcDesc ))  
           {
            wsprintf(strTmpShow," %04X   %04X     No  Function information ",
                     m_pTraceInfo[FramePoint].frameNo,
                     m_pTraceInfo[FramePoint].addr);
            if(hasFunction)
             { ShowLine(strTmpShow); hasFunction=FALSE; }
            }
            else
             { 
              wsprintf(strTmpShow," %04X   %04X     Funtion Enter: %s",
                     m_pTraceInfo[FramePoint].frameNo,
                     m_pTraceInfo[FramePoint].addr,strTmpTmp);
              ShowLine(strTmpShow); hasFunction=TRUE;  hasModule=TRUE;
              }
          //in function   
          while(
                m_pTraceInfo[FramePoint].addr>=funcStart &&
                m_pTraceInfo[FramePoint].addr<=funcEnd)
           { 
            if(TestKey(VK_ESCAPE)) return;
            FramePoint++;
            if(FramePoint>=AbiFrameNum)
             { 
              memcpy( &(m_pTraceInfo[0]),
                      &(m_pTraceInfo[AbiFrameNum-1]),
                      sizeof(TRACE_INFO) );
              do
               {        
                readDirect=NULL;  RecordFrameStart=1;
                AbiFrameNum=0;
                (this->*GetFrame)();   
                } while(BeginFrameNo<=EndFrameNo && AbiFrameNum==1);
              
              FramePoint=1; 
              }
            if(BeginFrameNo>EndFrameNo && FramePoint>=AbiFrameNum) break;
            } //while function 
            
          if(funcDesc!=0 && 0== LstGetSymbolName((LPSTR)strTmpTmp ,funcDesc ))  
           { 
            if(FramePoint==0) 
             {
//              AfxMessageBox("Is Your Trace Buffer corresponding to your source");
              return;
              }
            wsprintf(strTmpShow," %04X   %04X     Function Exit: %s",
                   m_pTraceInfo[FramePoint-1].frameNo,
                   m_pTraceInfo[FramePoint-1].addr,strTmpTmp);
            ShowLine(strTmpShow);  
            }
          if(BeginFrameNo>EndFrameNo && FramePoint>=AbiFrameNum) break;  
          }//while module     
            
        if(moduleDesc!=0 && 0== LstGetSymbolName((LPSTR)strTmpTmp,moduleDesc))  
         {   
          if(FramePoint==0) 
           {
//            AfxMessageBox("Is Your Trace Buffer corresponding to your source");
            return;
            }
          wsprintf(strTmpShow," %04X   %04X   Module Exit: %s",
                    m_pTraceInfo[FramePoint-1].frameNo,
                    m_pTraceInfo[FramePoint-1].addr,strTmpTmp);
          ShowLine(strTmpShow); 
          }
        
        }//while   frame
     } //while    whole
  }


  
//interface to shell  
void CListTrace::CmdShell(int nArgc, char* pszArgv[])
{                                       
    char*  stop_at;
    void (CListTrace::* myFunc) ();//to decide asm or c or ...
    int indexhere;
   
    // Assertion of the input parameters.                
    ASSERT( nArgc > 0 );
    for ( int i = 0; i <nArgc; i++ ) ASSERT( pszArgv[i] );
    
    int nErrorID = AbiGetTraceLastFrame((unsigned int *)(&(m_lastFrameNo)));
    if(g_bTraceClear)
    	m_lastFrameNo=0;
    
     if(ICE_OK != nErrorID)
    {
     DisplayErrorMessage(nErrorID);
     return;
    } 
    
    if(0==m_lastFrameNo)
    {
     ShowLine("Trace buffer empty.");
     return;
     }
    
    m_lastFrameNo--;
    
    //init     
    FrameQualify.setMode = 1; 
    FrameQualify.qlfyType[0] = 0;
    FrameQualify.qlfyType[4] = 0;
    FrameQualify.qlfyType[6] = 0;
    FrameQualify.qlfyType[8] = 0;
    FrameQualify.qlfyType[9] = 0;
    FrameQualify.qlfyType[10] = 0;
    indexhere=1;
    myFunc=CListTrace::ListTrcDataToShell;
    BeginFrameNo=0; EndFrameNo=m_lastFrameNo;
    ArgMax = nArgc;
    for (int ii=0; ii< ArgMax ; ii++) ArgPoint[ii] = pszArgv[ii];

    while(indexhere<ArgMax)
    {
     if(0 == _stricmp(ArgPoint[indexhere], "NUMBER") ) 
      {
      	char	pnumber[100];
      	wsprintf(pnumber, "The last frame number is %04X.", m_lastFrameNo);
      	ShowLine(pnumber);
      	myFunc=NULL;
      	break;
      }
     else
     if(0 == _stricmp(ArgPoint[indexhere], "SOURCE") ) 
      { myFunc=CListTrace::ListTrcCToShell; indexhere++; }
     else
     if(0 == _stricmp(ArgPoint[indexhere], "ASSEMBLE") ) 
      { myFunc=CListTrace::ListTrcAsmToShell; indexhere++; }
     else
     if(0 == _stricmp(ArgPoint[indexhere], "MIXED") ) 
      { myFunc=CListTrace::ListTrcMixToShell; indexhere++; }
     else
     if(0 == _stricmp(ArgPoint[indexhere], "MODULE") ) 
      { myFunc=CListTrace::ListTrcModuleToShell; indexhere++; } 
     else 
     if(ISLISTFRAME(ArgPoint[indexhere]) ) 
      { BeginFrameNo = (WORD)strtoul(ArgPoint[indexhere],&stop_at,16); indexhere++;}
     else 
     if(0 == _stricmp(ArgPoint[indexhere], "ADDRESS") )
      { SetAddr(&indexhere); }
     else
     if(0 == _stricmp(ArgPoint[indexhere], "DATUM") )
      { SetData(&indexhere); }
     else
     if(0 == _stricmp(ArgPoint[indexhere], "STATUS") )
      { SetStatus(&indexhere); }
     }//while
     if(myFunc)
    	(this->*myFunc) ( );

    //SHOW ELAPSE TIME HERE ADDED BY JOHN 96.1.30
    //modify by chris, May 10, 96
//    unsigned short day,hour,minute,second,ms,us;
    CString strShowTime; 
    if(!GetElapseTime(strShowTime, 1))
		ErrGetErrorText(ER_TRCSVR_GETETIMEERR, strShowTime);
    
//    wsprintf(strShowTime.GetBuffer(70),"Elapse time : Day:%02u Hour:%02u Minute:%02u Second:%02u Ms:%04u Us:%04u",
//             day,hour,minute,second,ms,us);
//    strShowTime.ReleaseBuffer();
//    strShowTime="Elapse Time: "+strShowTime;
    ShowLine(strShowTime.GetBuffer(strShowTime.GetLength()));
    strShowTime.ReleaseBuffer();
//    strShowTime.ReleaseBuffer();
  
}//function
 
/*
STATUS CListTrace::GetElapseTime(unsigned short &day,unsigned short &hour,
    				   unsigned short &minute,unsigned short &second,
    				   unsigned short &ms,unsigned short &us)
{                                                          
 TIMER_COUNT TimerCount;
 STATUS status = AbiGetTimerCount(&TimerCount);
 if(status != ICE_OK) return status;
 
 unsigned long ulTmpDiv = 0xffffffff/1000;
 unsigned long ulTmpMod = 0xffffffff%1000;
 unsigned long ulTmpMs,ulTmpUs,ulTmpSecond,ulTmpMinute,ulTmpHour;
 
 ulTmpMod++;
 if (ulTmpMod==1000) { ulTmpMod=0;ulTmpDiv++; } 
 
 ulTmpMs = ulTmpDiv*(TimerCount.uchHighCount) + TimerCount.ulLowCount/1000;
 ulTmpUs = ulTmpMod*(TimerCount.uchHighCount) + TimerCount.ulLowCount%1000;
 ulTmpMs += ulTmpUs/1000; 
 ulTmpUs %=1000;
 //get us
 us = (unsigned short) ulTmpUs ;
 
 ulTmpSecond = ulTmpMs / 1000;
 //get ms
 ms = (unsigned short)(ulTmpMs%1000);
 
 ulTmpMinute = ulTmpSecond/60;
 //get second
 second = (unsigned short)(ulTmpSecond%60);
 
 ulTmpHour = ulTmpMinute/60;
 //get minute
 minute = (unsigned short)(ulTmpMinute%60);
 
 //get day
 day = (unsigned short)(ulTmpHour/24);
 //get hour         
 hour = (unsigned short)(ulTmpHour%24);
  
 return status;
 }
*/    				   
                                       
CListTrace::CListTrace()
{    
    dataValid=instValid=FALSE;
    cValid=FALSE;
                                   
    strTmpTmp=new char[MAXCHARSALINE]; 
    if(NULL == strTmpTmp)
    {
		ErrDisplayError(ER_OUT_OF_MEMORY);
    	ASSERT(0);
    }                   
    strTmpShow=new char[MAXCHARSALINE]; 
    if(NULL == strTmpShow)
    {
    ErrDisplayError(ER_OUT_OF_MEMORY);
    ASSERT(0);
    }         
    tmpTrcInst = (FrameInst far*)GlobalAllocPtr(GMEM_MOVEABLE,
                    sizeof(FrameInst)*MAX_TRCWIN_LINE);
    if(NULL == tmpTrcInst)
    {
    ErrDisplayError(ER_OUT_OF_MEMORY);
    ASSERT(0);
    }                                         
    tmpTrcInst2 = (FrameInst far*)GlobalAllocPtr(GMEM_MOVEABLE,
                    sizeof(FrameInst)*MAX_TRCWIN_LINE);
    if(NULL == tmpTrcInst2)
    {
    ErrDisplayError(ER_OUT_OF_MEMORY);
    ASSERT(0);
    }
    m_pTraceInfo = (TRACE_INFO far*)GlobalAllocPtr(GMEM_MOVEABLE,
                    sizeof(TRACE_INFO)*(MAX_INST_LINE));
    if(NULL==m_pTraceInfo)
    {
    ErrDisplayError(ER_OUT_OF_MEMORY);
    ASSERT(0);
    }
    
    tmpTrcData= (FrameData far*)GlobalAllocPtr(GMEM_MOVEABLE,
                 sizeof(FrameData)*MAX_TRCWIN_LINE);
    if(NULL == tmpTrcData)
    {
    ErrDisplayError(ER_OUT_OF_MEMORY);
    ASSERT(0);
    }
    
    tmpTrcData2= (FrameData far*)GlobalAllocPtr(GMEM_MOVEABLE,
                 sizeof(FrameData)*MAX_TRCWIN_LINE);
    if(NULL == tmpTrcData2)
    {
    ErrDisplayError(ER_OUT_OF_MEMORY);
    ASSERT(0);  
    }
    
    tmpTrcC= (FrameC far*)GlobalAllocPtr(GMEM_MOVEABLE,
                 sizeof(FrameC)*MAX_TRCWIN_LINE);
    if(NULL == tmpTrcC)
    {
    ErrDisplayError(ER_OUT_OF_MEMORY);
    ASSERT(0);
    }
    
    tmpTrcC2= (FrameC far*)GlobalAllocPtr(GMEM_MOVEABLE,
                 sizeof(FrameC)*MAX_TRCWIN_LINE);
    if(NULL == tmpTrcC2)
    {
    ErrDisplayError(ER_OUT_OF_MEMORY);
    ASSERT(0);
    } 
}   

CListTrace::~CListTrace()
{
    if(NULL!=tmpTrcInst)
    GlobalFreePtr(tmpTrcInst);
    if(NULL!=tmpTrcInst2)     
    GlobalFreePtr(tmpTrcInst2);
    if(NULL!=m_pTraceInfo)
    GlobalFreePtr(m_pTraceInfo);
    if(NULL != strTmpTmp)
    delete []strTmpTmp;
    if(NULL != strTmpShow)
    delete []strTmpShow;
    if(NULL != tmpTrcData)   
    GlobalFreePtr(tmpTrcData);
    if(NULL != tmpTrcData2)
    GlobalFreePtr(tmpTrcData2);
    if(NULL != tmpTrcC)
    GlobalFreePtr(tmpTrcC2);
    if(NULL != tmpTrcC2)
    GlobalFreePtr(tmpTrcC2);
}

//port command
void PortCmd(int /*nArgc*/, char* pszArgv[])
{
char* stop_at;
char strDisplay[25];
int  nErrorID;

    int port = (int)strtoul(pszArgv[1],&stop_at,16);
    ASSERT(port < 7&&port >= 0);
    
    switch(port)
    {
    case 0:
        nErrorID = AbiSetPort(PORT_P0);
        break;
    case 1:
        nErrorID = AbiSetPort(PORT_P1);
        break;
    case 2:
        nErrorID = AbiSetPort(PORT_P2);
        break;
    case 3:
        nErrorID = AbiSetPort(PORT_P3);
        break;                         
	case 4:
        nErrorID = AbiSetPort(PORT_P4);
        break;
    case 5:
        nErrorID = AbiSetPort(PORT_P5);
        break;
    case 6:
        nErrorID = AbiSetPort(PORT_P6);
        break;                                 
    }
    if(ICE_OK == nErrorID)
    {
    wsprintf(strDisplay,"Port %i is set.",port);
    g_nPort=port;
    ShowLine(strDisplay);
    }    
    else
    DisplayErrorMessage(nErrorID);
}

//init trace
int InitTrace(void)
{ 

 if(!ev1.Init()) return FALSE;
 if(!ev2.Init()) return FALSE;
 if(!ev3.Init()) return FALSE;
 if(!Le1.Init()) return FALSE;
 if(!Le2.Init()) return FALSE;
 if(!Trig.Init()) return FALSE;
 if(!qlfy.Init()) return FALSE;
 if(AbiSetTraceStatus(traceStatus))
	{ 
  		ErrDisplayError(ER_TRCSVR_INITTRACEERR);
  		return FALSE; 
  	}	
 if(AbiSetTimerStatus(timerStatus))
	{ 
		ErrDisplayError(ER_TRCSVR_INITTIMERERR);
		return FALSE; 
	}
 return TRUE;
 
 }

/////////////////////////////////////////////////////////////////////////////
//begin mark by Chris
typedef	struct tagALLCONFIG
	{
	 BOOL			saveflag;	
	 BOOL 			traceonoff;
	 BOOL			timeronoff;
	 BOOL			triggeronoff;
//	 TRIGGER_LOGIC	trigger;
//	 TRIGGER_LEVEL	level1;
//	 TRIGGER_LEVEL	level2;
	 BOOL			ev1onoff;
//	 BUS_EVENT		ev1;
	 BOOL			ev2onoff;
//	 BUS_EVENT		ev2;
	 BOOL			ev3onoff;
//	 BUS_EVENT		ev3;
	 BOOL			qualifyonoff;
//	 QUALIFY		qualify;
	}
	ALLCONFIG;

ALLCONFIG	allconfig;	 

extern BOOL DoMapRestore();             // Restore the map setting from the file
extern void DoMapSave();                // Save the map setting to the file

void	SaveAllConfig(void)   
{
BOOL	bFailtracetimer=FALSE;


UINT	status;

//map:
    DoMapSave();

//trace, timer:
	if(AbiGetCpuStatus(&status)!=ICE_OK)            //by chris
    {
    	bFailtracetimer=TRUE;
    	allconfig.traceonoff = FALSE;
		allconfig.timeronoff = FALSE;
    }         
    else    
    { 
		allconfig.traceonoff = (status&0x0004)?TRUE:FALSE;
		allconfig.timeronoff = (status&0x0100)?TRUE:FALSE;
	}

//trigger(use infomation save in host computer):
	allconfig.triggeronoff=Trig.m_nOnOffFlg;
 //	allconfig.trigger.trigFlag = Trig.m_trig.TrigFlg;
//	allconfig.trigger.runFlag =  Trig.m_trig.RunFlg;
//	allconfig.trigger.delayCount=Trig.m_trig.DlayCnt;
//	allconfig.trigger.levelCount=Trig.m_trig.LevelCount;
//	for(i=0;i<4;i++)
//		allconfig.trigger.levelID[i]=Trig.m_trig.LevelID[i];

//level(use infomation save in host computer):
//	allconfig.level1.traceFlag=Le1.m_levelStructSave.TraceFlg;
//	allconfig.level1.timerFlag=Le1.m_levelStructSave.TimerFlg;
//	allconfig.level1.dwCond  = Le1.m_levelStructSave.Condition;	
	
//	allconfig.level2.traceFlag=Le2.m_levelStructSave.TraceFlg;
//	allconfig.level2.timerFlag=Le2.m_levelStructSave.TimerFlg;
//	allconfig.level2.dwCond  = Le2.m_levelStructSave.Condition;

//event(use infomation save in host computer):
	allconfig.ev1onoff=!ev1.m_nClearflag;
//	if(allconfig.ev1onoff)
//		allconfig.ev1=ev1.m_busEv;
	allconfig.ev2onoff=!ev2.m_nClearflag;
//	if(allconfig.ev2onoff)
//		allconfig.ev2=ev2.m_busEv;
	allconfig.ev3onoff=!ev3.m_nClearflag;
//	if(allconfig.ev3onoff)
//		allconfig.ev3=ev3.m_extEv;
		
//qualify(use infomation save in host computer):
	allconfig.qualifyonoff=!qlfy.m_nClearflag;
//	if(allconfig.qualifyonoff)
//		allconfig.qualify=qlfy.m_qlfy;

//breakpoint:

//exit process:
	if(bFailtracetimer)
		ErrDisplayError(ER_TRCSVR_GETERROR1);
	allconfig.saveflag=TRUE;
	return;
}

void	RestoreAllConfig(void)
{
BOOL	bFailTrace=FALSE;
BOOL	bFailTimer=FALSE;
BOOL	bFailTrigger=FALSE;
BOOL	bFailLevel=FALSE;
BOOL	bFailEvent=FALSE;
BOOL	bFailQualify=FALSE;
BOOL	bFailBreakpoint=FALSE;
	
STATUS	nErrorID;

		ASSERT(allconfig.saveflag);

//map:
		DoMapRestore();
		
//restore trace, timer:
		nErrorID = AbiSetTraceStatus((FLAG)allconfig.traceonoff);
        if(ICE_OK != nErrorID)
        	bFailTrace=TRUE;

		nErrorID = AbiSetTimerStatus((FLAG)allconfig.timeronoff);
        if(ICE_OK != nErrorID)
        	bFailTimer=TRUE;

//restore trigger:
		nErrorID = AbiSetTrigStatus((FLAG)allconfig.triggeronoff);
		if(ICE_OK != nErrorID)
        	bFailTrigger=TRUE;
        TRIGGER_LOGIC	trigger;
    	memcpy(&trigger,&Trig.m_trig,sizeof(TRIGGER_LOGIC));
		nErrorID = AbiSetTrigLogic(trigger);
		if(ICE_OK != nErrorID)
        	bFailTrigger=TRUE;

//restore level:
		TRIGGER_LEVEL	level;
		memcpy(&level, &Le1.m_levelStructSave, sizeof(TRIGGER_LEVEL));
		nErrorID = AbiSetTrigLevel(1,level);
    	if (ICE_OK != nErrorID)
			bFailLevel=TRUE;
		memcpy(&level, &Le2.m_levelStructSave, sizeof(TRIGGER_LEVEL));
		nErrorID = AbiSetTrigLevel(2,level);
    	if (ICE_OK != nErrorID)
			bFailLevel=TRUE;
			
//restore event:
		if(!allconfig.ev1onoff)
			nErrorID = AbiClrEvent(1);
		else
			nErrorID = AbiSetEvent(ev1.m_busEv);
		if(!allconfig.ev2onoff)
			nErrorID = AbiClrEvent(2);
		else
			nErrorID = AbiSetEvent(ev2.m_busEv);
		if(!allconfig.ev3onoff)
			nErrorID = AbiClrEvent(3);
		else
			nErrorID = AbiSetEvent(ev3.m_extEv);
		if (ICE_OK != nErrorID)
			bFailEvent=TRUE;

//restore qualify:
		if(!allconfig.qualifyonoff)
			nErrorID = AbiClrQualify();
		else
			nErrorID = AbiSetQualify(qlfy.m_qlfy);
		if (ICE_OK != nErrorID)
			bFailQualify=TRUE;
			
//restore breakpoint:			
		if(!RecoverBP())
			bFailBreakpoint=TRUE;

		if(bFailTrace||bFailTimer||bFailTrigger||bFailLevel
			||bFailEvent||bFailQualify||bFailBreakpoint)
		{
			CString errmsg;
			errmsg="Cannot restore ";
			if(bFailTrace)
				errmsg+="TRACE, ";
			if(bFailTimer)
				errmsg+="TIMER, ";
			if(bFailTrigger)
				errmsg+="TRIGGER, ";
			if(bFailLevel)
				errmsg+="LEVEL, ";
			if(bFailEvent)
				errmsg+="EVENT, ";
			if(bFailQualify)
				errmsg+="QUALIFY, ";
			if(bFailBreakpoint)
				errmsg+="BREAKPOINT  ";
			errmsg=errmsg.Left(errmsg.GetLength()-2);
			errmsg+=" infomation to FW!";
			AfxMessageBox((const char*)errmsg);
		}
}
 
BOOL GetElapseTime(CString& etime, int fromshell)
{
    int i;
    char buf[50];
    float timeinns, num;
    TIMER_COUNT TimerCount;
    CString tmp, tmp2;
    
    etime.Empty();
    STATUS status = AbiGetTimerCount(&TimerCount);
    if(status != ICE_OK)
        return FALSE;

	timeinns=(TimerCount.uchHighCount*0x10000000*0x10*1.0+TimerCount.ulLowCount)
				*1000;
	//12345678    (etime: 8 char)
	//      us
	sprintf(buf, "%e", timeinns);
	tmp=buf;
	i=tmp.Find('e');
	tmp2=tmp.Left(i);
	num=atof(tmp2);
	tmp2=tmp.Right(4);
	i=atoi(tmp2);
	//now num is the time, i is base
	ASSERT(i>=0);
	if(i<3)
	{
		num*=mypow(10, i);
		i=0;		//in ns
	}
	else if(i<6)
	{
		num*=mypow(10, i-3);
		i=1;		//in us
	}
	else if(i<9)
	{
		num*=mypow(10, i-6);
		i=2;		//in ms
	}
	else
	{
		num*=mypow(10, i-9);
		i=3;		//in s
	}
	sprintf(buf, "%06f", num);
	if(fromshell)	
		etime="Elapse time: ";
	else
	{
	    if(buf[5]<='9'&&buf[5]>='0'&&
	    	buf[6]<='9'&&buf[6]>='5')
	    {
	    	if(buf[5]=='9'&&buf[4]<='8'&&buf[4]>='0')
	    		buf[4]++,
	    		buf[5]='0';
	    	else
	    		buf[5]++;
		}
		buf[6]=NULL;
	}
	etime+=buf;
	if(i==0)
		etime+="ns";
	else if(i==1)
		etime+="us";
	else if(i==2)
		etime+="ms";
	else
		etime+=" s";
	return TRUE;
}

float mypow(int a, int b)
{
float val=1;

	for(int i=0; i<b; i++)
		val=a*val;
	return val;
}

////////////////////////////(EOF)//////////////////////////////////////
