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

/***************************************************************************
**
** File name : TRCSRVWN.CPP 
** Author:BRIGHT CHEN
** Followed by : John Chow, Chris Fang.
** Description:
**
**
**    Finished date: 1995.9.1
**    Edit in "BOOL CListTrace::ListTrcInstToWnd(int readDirect,WORD* beginNo,WORD* endNo,
**                                WORD* LineCnt,FrameInst* frameInst)"
**         to fix bug                         
**    Edit in "BOOL ListTrcCToWnd(int readDirect,WORD* beginNo,WORD* endNo,
**                      WORD* LineCnt,FrameC* frameC)"
**         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
**	  add trace on fly spec:
**					modify function: 1. ListTrcDataToWnd
**									 2. ListTrcInstToWnd
**									 3. ListTrcCToWnd
**    Copyright (C) 1995 Microtek International, Inc.
**    All Rights Reserved
**
****************************************************************************/


//////////////////////////////////
//trcserve.cpp
//Bright Cheng
//95/4
//////////////////////////////////
#include "stdafx.h"
#include "stdlib.h"
#include "string.h"
#include "ctype.h"

#include "abibase.h"
#include "trcserve.h"
#include "cpust.h"
#include "uicom.h"
//#include "cpuserve.h"

QUALIFY  softQlfy;

extern UINT GetCpuId();
int TestKeyNoRemove(WORD wKey);
extern int SrcIsLoaded(void); //from symbol(gates) 
extern void DisplayErrorMessage(int);
extern void DisplayErrorMessageBox(int);
extern CString SrcGetModuleFullName(const char *);//from roger
extern unsigned char TRCGetInstLen(unsigned char);
extern  int TRCGetInst(unsigned short,unsigned char*,
                       unsigned char,unsigned char*);

extern void TraceWnd(unsigned char trace);

extern CListTrace* pTrcSvr;
extern CSrcFile SrcFile;

//interface to trace window
BOOL ListTrcDataToWnd(int readDirect,WORD* beginNo,WORD* endNo,
                        WORD* LineCnt,FrameData* frameData)
{               
unsigned char	status;
WORD	Astartf=*beginNo;

    WORD tmp=*LineCnt;          
    ASSERT(tmp<=MAX_TRCWIN_LINE);
    if(!GetCpuStatus(status))
    	return FALSE;
	if(status==STATUS_GO)				//CPU is run
		TraceWnd(0);					//TRACE OFF
    BOOL result=pTrcSvr->ListTrcDataToWnd(readDirect,beginNo,endNo,
                                   LineCnt,frameData);
	if(readDirect==1&&Astartf==frameData[0].phisicalNo&&(tmp/2<*LineCnt))
	{
		ASSERT(*LineCnt);
		(*LineCnt)--;
		for(int i=0; i<*LineCnt; i++)
			frameData[i]=frameData[i+1];
	}
	
/*    for(WORD i=*LineCnt;i<tmp;i++)
     { 
      wsprintf(frameData[i].frameNo,"%4s"," ");
      wsprintf(frameData[i].addr,"%4s"," ");
      wsprintf(frameData[i].data,"%2s"," ");
      wsprintf(frameData[i].status,"%2s"," ");
      wsprintf(frameData[i].portdata,"%2s"," ");
      wsprintf(frameData[i].spare,"%5s"," ");                                           
      }
    *LineCnt=tmp;  
*/
    return result;  
}
                              
//interface to trace window                              
BOOL ListTrcInstToWnd(int readDirect,WORD* beginNo,WORD* endNo,
                        WORD* LineCnt,FrameInst* frameInst)
{                                                              
unsigned char	status;    
WORD	Astartf=*beginNo;
WORD tmp=*LineCnt;          

    ASSERT(*LineCnt<=MAX_TRCWIN_LINE);
    if(!GetCpuStatus(status))
    	return FALSE;
	if(status==STATUS_GO)				//CPU is run
		TraceWnd(0);					//TRACE OFF
    BOOL result = pTrcSvr->ListTrcInstToWnd(readDirect,beginNo,endNo,
                                      LineCnt,frameInst);
    if(!*LineCnt&&readDirect==2&&tmp>2)
    {
     	*LineCnt=tmp-1;
     	//the server is very stupid, so we must do something stupid.
     	ASSERT(pTrcSvr->instLen>0);
     	pTrcSvr->instLen=pTrcSvr->instLen-1;
     	result = pTrcSvr->ListTrcInstToWnd(readDirect,beginNo,endNo,
                                      LineCnt,frameInst);
    }
	if(readDirect==1&&Astartf==frameInst[0].phisicalNo&&(tmp/2<*LineCnt))
	{
		ASSERT(*LineCnt);
		(*LineCnt)--;
		for(int i=0; i<*LineCnt; i++)
			frameInst[i]=frameInst[i+1];
	}

    /*if(*LineCnt==0)                   
     { 
      WORD wTmptmp=1;
      result = pTrcSvr->ListTrcInstToWnd(-1,beginNo,endNo,
                                         &wTmptmp,frameInst);                                  
      *LineCnt=wTmptmp;
      }                          */
/*    for(WORD i=*LineCnt;i<tmp;i++)                            
     { 
      wsprintf(frameInst[i].frameNo,"%4s"," ");
      wsprintf(frameInst[i].addr,"%4s"," ");
      wsprintf((char *)(&(frameInst[i].instruction[0])),"%s"," ");
      }           
    *LineCnt=tmp;                          
*/
    return result;                         
}
/*
//interface to trace window
BOOL ListTrcCToWnd(int readDirect,WORD* beginNo,WORD* endNo,
                        WORD* LineCnt,FrameC* frameC)
{    
unsigned char	status;    

    WORD tmp=*LineCnt;          
    
    if(0 != SrcIsLoaded())
     {
      AfxMessageBox("Please load source first!");
      *LineCnt=0;
      for(WORD i=*LineCnt;i<tmp;i++)                            
       { 
        wsprintf(frameC[i].frameNo,"%4s"," ");
        wsprintf(frameC[i].line,"%4s"," ");
        wsprintf((char *)(&(frameC[i].c[0])),"%s"," ");
        }           
      *LineCnt=tmp;                          
      return FALSE;
      }
  
    
    ASSERT(tmp<=MAX_TRCWIN_LINE);
    if(!GetCpuStatus(status))
    	return FALSE;
	if(status==STATUS_GO)				//CPU is run
		TraceWnd(0);					//TRACE OFF

    BOOL result = pTrcSvr->ListTrcCToWnd(readDirect,beginNo,endNo,
                                      LineCnt,frameC);
//    if(*LineCnt==0)
//     {
//      WORD wTmptmp=1;                                
//      result = pTrcSvr->ListTrcCToWnd(-1,beginNo,endNo,
//                                      &wTmptmp,frameC);
//      *LineCnt=wTmptmp;                                
/ /     }                                
    for(WORD i=*LineCnt;i<tmp;i++)                            
     { 
      wsprintf(frameC[i].frameNo,"%4s"," ");
      wsprintf(frameC[i].line,"%4s"," ");
      wsprintf((char *)(&(frameC[i].c[0])),"%s"," ");
      }           
    *LineCnt=tmp;                          
    return result;                                   
}
*/

char* statusTbl[5] = { " S"," F"," R"," W","AK" };

//SHOW TRACE DATA IN TRACE WINDOW
void CListTrace::GetDataForWin(BOOL isUp,unsigned short &beginPos,
                 unsigned short &endPos,unsigned short &length)
{ 
  if(length>MAX_TRCWIN_LINE) length=MAX_TRCWIN_LINE;
  if(length==0) return;
  
  if(!isUp)
  {
   readDirect=NULL;  RecordFrameStart=0;
   AbiFrameNum=0;
   
   while(BeginFrameNo<=EndFrameNo )
    {         
     if(TestKeyNoRemove(VK_ESCAPE)) 
     { 
     	/*length=0; return;*/ break; 
     	}
     GetAbiFrame(length);
     RecordFrameStart= AbiFrameNum;
     if(AbiFrameNum>=length) break;
     }
     
   if(AbiFrameNum<length) length=AbiFrameNum; 
   for(unsigned short i=0;i<length;i++)
    {                                            
     //if(TestKeyNoRemove(VK_ESCAPE)) { length=0; 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';
        }            
        
     tmpTrcData2[i].phisicalNo=m_pTraceInfo[i].frameNo;
     wsprintf(tmpTrcData2[i].frameNo,"%04X",m_pTraceInfo[i].frameNo);
     if(g_nBankNum)
     {
     	if(status==2||status==3)
     	    wsprintf(tmpTrcData2[i].addr," X:%04X", m_pTraceInfo[i].addr);
     	else
     		wsprintf(tmpTrcData2[i].addr,"P%d:%04X",GetSpace(m_pTraceInfo[i].port)-6, m_pTraceInfo[i].addr);
     }
     else
     	wsprintf(tmpTrcData2[i].addr,"%04X",m_pTraceInfo[i].addr);
     wsprintf(tmpTrcData2[i].data,"%02X",m_pTraceInfo[i].data);
     wsprintf(tmpTrcData2[i].status,"%2s",statusTbl[status]);
     wsprintf(tmpTrcData2[i].portdata,"%02X",m_pTraceInfo[i].port);
     wsprintf(tmpTrcData2[i].spare,"%5s",strBit);
     }//for
     beginPos=0; endPos=length-1;
     
   }  //if
   else//isUp=true
   {
    if(BeginFrameNo==0) //is top and if Lane is stupid!!!
     {
      length=0;   return ;
      }
    WORD beginFrameNoBak;
    readDirect=NULL;  RecordFrameStart=0;
    AbiFrameNum=0;   beginPos=MAX_TRCWIN_LINE-1;
    EndFrameNo=BeginFrameNo-1;
    BeginFrameNo=(BeginFrameNo>=length)?BeginFrameNo-length:0;
    while(BeginFrameNo<=EndFrameNo)
     { 
      if(TestKeyNoRemove(VK_ESCAPE)) { /*length=0; return;*/break; }                 
      beginFrameNoBak=BeginFrameNo;
      GetAbiFrame();          
      ASSERT(AbiFrameNum<=length);
      for(int i=AbiFrameNum-1;i>=0;i--)
       {                                          
        //if(TestKeyNoRemove(VK_ESCAPE)) { length=0; 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';
          }            
        
        tmpTrcData2[beginPos-(AbiFrameNum-1-i)].phisicalNo=
                    m_pTraceInfo[i].frameNo;
        wsprintf(tmpTrcData2[beginPos-(AbiFrameNum-1-i)].frameNo,"%04X",
               m_pTraceInfo[i].frameNo);
        if(g_nBankNum)
        {
        	if(status==2||status==3)
        		wsprintf(tmpTrcData2[beginPos-(AbiFrameNum-1-i)].addr," X:%04X",
               		m_pTraceInfo[i].addr);
        	else
        		wsprintf(tmpTrcData2[beginPos-(AbiFrameNum-1-i)].addr,"P%d:%04X",
               		GetSpace(m_pTraceInfo[i].port)-6, m_pTraceInfo[i].addr);
        }
        else
        	wsprintf(tmpTrcData2[beginPos-(AbiFrameNum-1-i)].addr,"%04X",
               m_pTraceInfo[i].addr);
        wsprintf(tmpTrcData2[beginPos-(AbiFrameNum-1-i)].data,"%02X",
               m_pTraceInfo[i].data);
        wsprintf(tmpTrcData2[beginPos-(AbiFrameNum-1-i)].status,"%2s",
               statusTbl[status]);
        wsprintf(tmpTrcData2[beginPos-(AbiFrameNum-1-i)].portdata,
               "%02X",m_pTraceInfo[i].port);
        wsprintf(tmpTrcData2[beginPos-(AbiFrameNum-1-i)].spare,"%5s",
               strBit);
        }//for     
      ASSERT(beginPos>=AbiFrameNum);
      beginPos=beginPos-AbiFrameNum;
      ASSERT(length>=AbiFrameNum);
      length-=AbiFrameNum;         
      BeginFrameNo=beginFrameNoBak;
      if(BeginFrameNo==0) break;
      if(length<=0) break;
      EndFrameNo=BeginFrameNo-1;
      BeginFrameNo=(BeginFrameNo>=length)?BeginFrameNo-length:0; 
      }    //while
      
    length=MAX_TRCWIN_LINE-1-beginPos;  
    if(beginPos !=  MAX_TRCWIN_LINE-1) beginPos++;
    
    }//else
 }
                                  
//SHOW TRACE INSTRUCTION IN TRACE WINDOW                                  
void CListTrace::GetAsmForWin(BOOL isUp,unsigned short &beginPos,
                 unsigned short &,unsigned short &length)
{ 
  if(length>MAX_TRCWIN_LINE) length=MAX_TRCWIN_LINE;
  if(length==0) return;
  
  if(!isUp)
  {
   readDirect=NULL;  RecordFrameStart=0;
   AbiFrameNum=0;
   if(!AbiFrameNum)
   {
   		AbiFrameNum=(AbiFrameNum|0xf)&0x100c;
   		
   }
   unsigned short lengthBak=length;                        
   beginPos=0; length=0;
   
   while(BeginFrameNo<=EndFrameNo)
   {
     WORD FramePoint;
     
     if(TestKeyNoRemove(VK_ESCAPE)) { 
     	//length=0; return; 
     	break;
     }
          
     (this->*GetFrame)(lengthBak*9);
     if(length>=lengthBak) return;
     FramePoint=0; 
           
     while(FramePoint<AbiFrameNum)
      {              
        WORD FramePointTmp;                          
        /*if(TestKeyNoRemove(VK_ESCAPE)) { 
     	//length=0; return; 
     	break;
     	} */
        
        if(length>=lengthBak) 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
          {   
           tmpTrcInst2[length].phisicalNo=m_pTraceInfo[FramePointTmp].frameNo;
           wsprintf(tmpTrcInst2[length].frameNo,"%04X",m_pTraceInfo[FramePointTmp].frameNo);
           if(g_nBankNum)
           		wsprintf(tmpTrcInst2[length].addr,"P%d:%04X",GetSpace(m_pTraceInfo[FramePointTmp].port)-6, m_pTraceInfo[FramePointTmp].addr);
           else
           		wsprintf(tmpTrcInst2[length].addr,"%04X",m_pTraceInfo[FramePointTmp].addr);
           if(strlen(strTmpTmp)>126) strTmpTmp[127]=0;
           wsprintf((char *)(&(tmpTrcInst2[length].instruction[0])),"%s",strTmpTmp);
           length++;
           RecordFrameStart=0;
           }
        
        }        
     }
   
   }  //if
   else//isUp=true
   {
    if(BeginFrameNo==0) //is top and if Lane is stupid!!!
     {
      length=0;   return;
      }
    WORD beginFrameNoBak; unsigned short lengthBak=length;
    unsigned short tmp1,s_No;
    unsigned short tmpStatus_s[MAX_INST_LINE+1];
    
    readDirect=NULL;  RecordFrameStart=0;
    AbiFrameNum=0;   beginPos=MAX_TRCWIN_LINE-1;
    EndFrameNo=BeginFrameNo-1;    length=0;    
    
    tmp1=((lengthBak-length)*9>MAX_INST_LINE)
          ?MAX_INST_LINE:(lengthBak-length)*9;
    BeginFrameNo=(BeginFrameNo>=tmp1)?BeginFrameNo-tmp1:0;
    while(BeginFrameNo<=EndFrameNo)
     { 
      if(TestKeyNoRemove(VK_ESCAPE)) { 
      	//length=0; return; 
      	break;
      }

      beginFrameNoBak=BeginFrameNo;
      (this->*GetFrame)();          
      BeginFrameNo=beginFrameNoBak;
      //get status=s frames
      s_No=0; 
      for(unsigned short i=0;i<AbiFrameNum;i++)
       if((m_pTraceInfo[i].status&0x7)==STATUS_S) tmpStatus_s[s_No++]=i;
       
      if(s_No!=0)
      for(int ii=s_No-1;ii>=0;ii--)
       {
        if(TestKeyNoRemove(VK_ESCAPE)) { length=0; return; }
        unsigned short tmp2;
        tmp2=tmpStatus_s[ii];
        GetAsmStr(&tmp2,(unsigned char *)strTmpTmp);
        tmp2=tmpStatus_s[ii]; 
        tmpTrcInst2[beginPos].phisicalNo=m_pTraceInfo[tmp2].frameNo;
        wsprintf(tmpTrcInst2[beginPos].frameNo,"%04X",m_pTraceInfo[tmp2].frameNo);
       if(g_nBankNum)
       		wsprintf(tmpTrcInst2[beginPos].addr,"P%d:%04X",GetSpace(m_pTraceInfo[tmp2].port)-6, m_pTraceInfo[tmp2].addr);
       else
        	wsprintf(tmpTrcInst2[beginPos].addr,"%04X",m_pTraceInfo[tmp2].addr);
        if(strlen(strTmpTmp)>126) strTmpTmp[127]=0;
        wsprintf((char *)(&(tmpTrcInst2[beginPos].instruction[0])),"%s",strTmpTmp);
        if(beginPos==0) break;
        beginPos--; length++;
        if(length==lengthBak) break;
        }//for     
      if(length==lengthBak) break; 
      if(BeginFrameNo==0) break;
      if(s_No>0)
       {         
        BeginFrameNo=m_pTraceInfo[tmpStatus_s[0]].frameNo;
        EndFrameNo=BeginFrameNo-1;
        tmp1=((lengthBak-length)*4>MAX_INST_LINE)?MAX_INST_LINE:(lengthBak-length)*4;
        BeginFrameNo=(BeginFrameNo>=tmp1)?BeginFrameNo-tmp1:0;
        }
       else 
        {                             
         tmp1=((lengthBak-length)*4>MAX_INST_LINE-(EndFrameNo-beginFrameNoBak+1))
              ?MAX_INST_LINE-(EndFrameNo-beginFrameNoBak+1):(lengthBak-length)*4;
         BeginFrameNo=(beginFrameNoBak>=tmp1)?beginFrameNoBak-tmp1:0;
         }
      }    //while
      
    length=MAX_TRCWIN_LINE-1-beginPos;  
    if(beginPos !=  MAX_TRCWIN_LINE-1) beginPos++;
    
    }//else
 }
                        
//SERVE FOR GetDataForWin    
BOOL CListTrace::ListTrcDataToWnd(int readDirect,WORD* beginNo,WORD* endNo,
                                  WORD* LineCnt,FrameData* frameData)
{                               
int nErrorID=ICE_OK;

	if(g_bTraceClear)
		m_lastFrameNo=0;
	else
		nErrorID=AbiGetTraceLastFrame((unsigned int *)(&(m_lastFrameNo)));
  
  if(ICE_OK != nErrorID)
    {                
     DisplayErrorMessageBox(nErrorID);
     return FALSE;
     } 
                  
  if(m_lastFrameNo==0) 
   { 
    *endNo=*beginNo;   *LineCnt=0;
    return FALSE;
    }
                  
  m_lastFrameNo--;   
  
  if(*beginNo>m_lastFrameNo) 
   {                                                            
    readDirect=-2;
    *beginNo=m_lastFrameNo+1;
    }
    
  EndFrameNo=m_lastFrameNo;
                 
  memcpy(&(FrameQualify) ,&(softQlfy) ,sizeof(QUALIFY));
  
  unsigned short endPos,beginPos,length; 
  WORD tmp;
    
  switch(readDirect)
   {       
    case-2:
           BeginFrameNo=*beginNo; readDirect=NULL;
           length=*LineCnt;
           GetDataForWin(TRUE,beginPos,endPos,length);
           ASSERT(length<=*LineCnt);
           
           if(!dataValid) 
            {       
             memcpy(&(tmpTrcData[0]),&(tmpTrcData2[beginPos]),
                    sizeof(FrameData)*length); 
             memcpy(frameData,tmpTrcData,sizeof(FrameData)*length);       
             if(length==0) 
              { 
               *LineCnt=length;
               *endNo=*beginNo;
               return FALSE;
               }
             *LineCnt=length;
             *beginNo=frameData[0].phisicalNo;
             *endNo= frameData[*LineCnt-1].phisicalNo;
             dataValid=TRUE;  dataLen= *LineCnt;
             return TRUE;
             }
           
           tmp=*LineCnt-length;
           if(tmp>dataLen) tmp=dataLen;   
           memcpy(frameData,&(tmpTrcData[0]),
                  sizeof(FrameData)*tmp);
           memcpy(&(tmpTrcData[0]),&(tmpTrcData2[beginPos]),
                  sizeof(FrameData)*length);
           memcpy(&(tmpTrcData[length]),frameData,
                  sizeof(FrameData)*tmp);
           length+=tmp;
           memcpy(frameData,tmpTrcData,sizeof(FrameData)*length);
           *LineCnt=length;
           *beginNo=frameData[0].phisicalNo;
           *endNo= frameData[*LineCnt-1].phisicalNo;
           dataValid=TRUE;  dataLen= *LineCnt;
           if(dataLen==0) dataValid=FALSE;
           break;
    case-1:
           if(!dataValid) 
            {
             BeginFrameNo=*beginNo; readDirect=NULL;
             length=*LineCnt;
             GetDataForWin(TRUE,beginPos,endPos,length);
             ASSERT(length<=*LineCnt);             
             memcpy(&(tmpTrcData[0]),&(tmpTrcData2[beginPos]),
                    sizeof(FrameData)*length); 
             memcpy(frameData,tmpTrcData,sizeof(FrameData)*length);       
             if(length==0) 
              { 
               *LineCnt=length;
               *endNo=*beginNo;
               return FALSE;
               }
             *LineCnt=length;
             *beginNo=frameData[0].phisicalNo;
             *endNo= frameData[*LineCnt-1].phisicalNo;
             dataValid=TRUE;  dataLen= *LineCnt;
             return TRUE;
             }
           
           BeginFrameNo=*beginNo; readDirect=NULL;
           length=1;
           GetDataForWin(TRUE,beginPos,endPos,length);
           ASSERT(length<=*LineCnt);          
           tmp=*LineCnt-length;
           if(tmp>dataLen) tmp=dataLen; 
           memcpy(frameData,&(tmpTrcData[0]),
                  sizeof(FrameData)*tmp);
           memcpy(&(tmpTrcData[0]),&(tmpTrcData2[beginPos]),
                  sizeof(FrameData)*length);
           memcpy(&(tmpTrcData[length]),frameData,
                  sizeof(FrameData)*tmp);
           
           length+=tmp;
           memcpy(frameData,tmpTrcData,sizeof(FrameData)*length);
           *LineCnt=length;
           *beginNo=frameData[0].phisicalNo;
           *endNo= frameData[*LineCnt-1].phisicalNo;
           dataValid=TRUE;  dataLen= *LineCnt;
           if(dataLen==0) dataValid=FALSE;
           break;
    case 0:                              
           BeginFrameNo=*beginNo; readDirect=NULL;
           length=*LineCnt;
           GetDataForWin(FALSE,beginPos,endPos,length);
           ASSERT(*LineCnt>=length);          
           if(length==0) 
            { *LineCnt=0; endNo=beginNo; dataValid=FALSE; return FALSE; }
           memcpy(tmpTrcData,tmpTrcData2,sizeof(FrameData)*length);
           memcpy(frameData,tmpTrcData,sizeof(FrameData)*length);
           *LineCnt=length;
           *beginNo=frameData[0].phisicalNo;
           *endNo= frameData[*LineCnt-1].phisicalNo;
           dataValid=TRUE;  dataLen= *LineCnt;
           if(dataLen==0) dataValid=FALSE;
           break;
           
    case 1:
           if(!dataValid) 
              {
               BeginFrameNo=*beginNo+1; 
               length=*LineCnt; 
               GetDataForWin(FALSE,beginPos,endPos,length);
               ASSERT(*LineCnt>=length);          
               if(length==0) { *LineCnt=0; endNo=beginNo; return FALSE; }
               memcpy(tmpTrcData,tmpTrcData2,sizeof(FrameData)*length);
               memcpy(frameData,tmpTrcData,sizeof(FrameData)*length);
               *LineCnt=length;
               *beginNo=frameData[0].phisicalNo;
               *endNo= frameData[*LineCnt-1].phisicalNo;
               dataValid=TRUE;  dataLen= *LineCnt;
               break;
               }  
           BeginFrameNo=tmpTrcData[dataLen-1].phisicalNo+1;
           length=1; 
           readDirect=NULL;
           GetDataForWin(FALSE,beginPos,endPos,length);
           ASSERT(*LineCnt>=length); 
           WORD tmpLen;
           tmpLen=*LineCnt-length;               
           if(tmpLen>dataLen) tmpLen=dataLen;
           memcpy(&(tmpTrcData[0]),&(tmpTrcData[dataLen-tmpLen]),
                  sizeof(FrameData)*tmpLen);
           memcpy(&(tmpTrcData[tmpLen]),&(tmpTrcData2[0]),
                  sizeof(FrameData)*length);                    
           *LineCnt=tmpLen+length;
           memcpy(frameData,tmpTrcData,sizeof(FrameData)*(*LineCnt));
           *beginNo=frameData[0].phisicalNo;
           *endNo= frameData[*LineCnt-1].phisicalNo;
           dataValid=TRUE;  dataLen= *LineCnt;
           if(dataLen==0) dataValid=FALSE;
           break; 
    case 2:
           BeginFrameNo=tmpTrcData[dataLen-1].phisicalNo+1;
           if(BeginFrameNo>m_lastFrameNo&&BeginFrameNo<m_lastFrameNo+*LineCnt)
           		BeginFrameNo=m_lastFrameNo;
           length=*LineCnt; 
           readDirect=NULL;
           GetDataForWin(FALSE,beginPos,endPos,length);
           ASSERT(*LineCnt>=length); 
           if(length==0) { *LineCnt=0; endNo=beginNo; return FALSE; }
           memcpy(tmpTrcData,tmpTrcData2,sizeof(FrameData)*length);
           memcpy(frameData,tmpTrcData,sizeof(FrameData)*length);
           *LineCnt=length;
           *beginNo=frameData[0].phisicalNo;
           *endNo= frameData[*LineCnt-1].phisicalNo;
           dataValid=TRUE;  dataLen= *LineCnt;
           if(dataLen==0) dataValid=FALSE;
           break;           
           
     }//switch
    
  return TRUE;  
 }

//SERVE FOR GetAsmForWin    
BOOL CListTrace::ListTrcInstToWnd(int readDirect,WORD* beginNo,WORD* endNo,
                                  WORD* LineCnt,FrameInst* frameInst)
{                               
int nErrorID=ICE_OK;

	if(g_bTraceClear)
		m_lastFrameNo=0;
	else
		nErrorID=AbiGetTraceLastFrame((unsigned int *)(&(m_lastFrameNo)));
  
  if(ICE_OK != nErrorID)
    {                
     DisplayErrorMessageBox(nErrorID);
     return FALSE;
     } 
                  
  if(m_lastFrameNo==0) 
   { 
    *endNo=*beginNo;   *LineCnt=0;
    return FALSE;
    }
                  
  m_lastFrameNo--;   
  
  if(*beginNo>m_lastFrameNo) 
   { 
    readDirect=-2;
    *beginNo=m_lastFrameNo+1;
    }
    
  EndFrameNo=m_lastFrameNo;
                 
  memcpy(&(FrameQualify) ,&(softQlfy) ,sizeof(QUALIFY));
  
  //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) )
       { 
        *endNo=*beginNo;   *LineCnt=0;
        return FALSE;
        }
      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);  
      }   
    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) )
        { 
         *endNo=*beginNo;   *LineCnt=0;
         return FALSE;
         }
       }
      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

      }
  
  unsigned short endPos,beginPos,length; 
  WORD tmp;
    
  switch(readDirect)
   {       
    case-2:
           BeginFrameNo=*beginNo; readDirect=NULL;
           length=*LineCnt;
           GetAsmForWin(TRUE,beginPos,endPos,length);
           ASSERT(length<=*LineCnt);
           
           if(!instValid) 
            {       
             memcpy(&(tmpTrcInst[0]),&(tmpTrcInst2[beginPos]),
                    sizeof(FrameInst)*length);
             memcpy(frameInst,tmpTrcInst,sizeof(FrameInst)*length);
             if(length==0) 
              { 
               *LineCnt=length;
               *endNo=*beginNo;
               return FALSE;
               }
             *LineCnt=length;
             *beginNo=frameInst[0].phisicalNo;
             *endNo= frameInst[*LineCnt-1].phisicalNo;
             instValid=TRUE;  instLen= *LineCnt;
             return TRUE;
             }
           
           tmp=*LineCnt-length;
           if(tmp>instLen) tmp=instLen;   
           memcpy(frameInst,&(tmpTrcInst[0]),
                  sizeof(FrameInst)*tmp);
           memcpy(&(tmpTrcInst[0]),&(tmpTrcInst2[beginPos]),
                  sizeof(FrameInst)*length);
           memcpy(&(tmpTrcInst[length]),frameInst,
                  sizeof(FrameInst)*tmp);
           length+=tmp;
           memcpy(frameInst,tmpTrcInst,sizeof(FrameInst)*length);
           *LineCnt=length;
           *beginNo=frameInst[0].phisicalNo;
           *endNo= frameInst[*LineCnt-1].phisicalNo;
           instValid=TRUE;  instLen= *LineCnt;
           if(instLen==0) instValid=FALSE;
           break;
    case-1:
           if(!instValid) 
            {
             BeginFrameNo=*beginNo; readDirect=NULL;
             length=*LineCnt;
             GetAsmForWin(TRUE,beginPos,endPos,length);
             ASSERT(length<=*LineCnt);             
             memcpy(&(tmpTrcInst[0]),&(tmpTrcInst2[beginPos]),
                    sizeof(FrameInst)*length);
             memcpy(frameInst,tmpTrcInst,sizeof(FrameInst)*length);
             if(length==0) 
              { 
               *LineCnt=length;
               *endNo=*beginNo;
               return FALSE;
               }
             *LineCnt=length;
             *beginNo=frameInst[0].phisicalNo;
             *endNo= frameInst[*LineCnt-1].phisicalNo;
             instValid=TRUE;  instLen= *LineCnt;
             return TRUE;
             }
           
           BeginFrameNo=*beginNo; readDirect=NULL;
           length=1;
           GetAsmForWin(TRUE,beginPos,endPos,length);
           ASSERT(length<=*LineCnt);          
           tmp=*LineCnt-length;
           if(tmp>instLen) tmp=instLen; 
           memcpy(frameInst,&(tmpTrcInst[0]),
                  sizeof(FrameInst)*tmp);
           memcpy(&(tmpTrcInst[0]),&(tmpTrcInst2[beginPos]),
                  sizeof(FrameInst)*length);
           memcpy(&(tmpTrcInst[length]),frameInst,
                  sizeof(FrameInst)*tmp);
           
           length+=tmp;
           memcpy(frameInst,tmpTrcInst,sizeof(FrameInst)*length);
           *LineCnt=length;
           *beginNo=frameInst[0].phisicalNo;
           *endNo= frameInst[*LineCnt-1].phisicalNo;
           instValid=TRUE;  instLen= *LineCnt;
           if(instLen==0) instValid=FALSE;
           break;
    case 0:                              
           BeginFrameNo=*beginNo; readDirect=NULL;
           length=*LineCnt;
           GetAsmForWin(FALSE,beginPos,endPos,length);
           ASSERT(*LineCnt>=length);          
           if(length==0) 
            { *LineCnt=0; endNo=beginNo;instValid=FALSE; return FALSE; }
           memcpy(tmpTrcInst,tmpTrcInst2,sizeof(FrameInst)*length);
           memcpy(frameInst,tmpTrcInst,sizeof(FrameInst)*length);
           *LineCnt=length;
           *beginNo=frameInst[0].phisicalNo;
           *endNo= frameInst[*LineCnt-1].phisicalNo;
           instValid=TRUE;  instLen= *LineCnt;
           if(instLen==0) instValid=FALSE;
           break;
           
    case 1:
           if(!instValid) 
              {
               BeginFrameNo=*beginNo+1; 
               length=*LineCnt; 
               readDirect=NULL;
               GetAsmForWin(FALSE,beginPos,endPos,length);
               ASSERT(*LineCnt>=length);          
               if(length==0) { *LineCnt=0; endNo=beginNo; return FALSE; }
               memcpy(tmpTrcInst,tmpTrcInst2,sizeof(FrameInst)*length);
               memcpy(frameInst,tmpTrcInst,sizeof(FrameInst)*length);
               *LineCnt=length;
               *beginNo=frameInst[0].phisicalNo;
               *endNo= frameInst[*LineCnt-1].phisicalNo;
               instValid=TRUE;  instLen= *LineCnt;
               break;
               }  
           BeginFrameNo=tmpTrcInst[instLen-1].phisicalNo+1;
           length=1; 
           readDirect=NULL;
           GetAsmForWin(FALSE,beginPos,endPos,length);
           ASSERT(*LineCnt>=length); 
           WORD tmpLen;
           tmpLen=*LineCnt-length;               
           if(tmpLen>instLen) tmpLen=instLen;
           memcpy(&(tmpTrcInst[0]),&(tmpTrcInst[instLen-tmpLen]),
                  sizeof(FrameInst)*tmpLen);
           memcpy(&(tmpTrcInst[tmpLen]),&(tmpTrcInst2[0]),
                  sizeof(FrameInst)*length);
           *LineCnt=tmpLen+length;
           memcpy(frameInst,tmpTrcInst,sizeof(FrameInst)*(*LineCnt));
           *beginNo=frameInst[0].phisicalNo;
           *endNo= frameInst[*LineCnt-1].phisicalNo;
           instValid=TRUE;  instLen= *LineCnt;
           if(instLen==0) instValid=FALSE;
           break; 
    case 2:                       
           if(!instValid) 
              {
               BeginFrameNo=*beginNo+1; 
               length=*LineCnt;
               readDirect=NULL; 
               GetAsmForWin(FALSE,beginPos,endPos,length);
               ASSERT(*LineCnt>=length);          
               if(length==0) { *LineCnt=0; endNo=beginNo; return FALSE; }
               memcpy(tmpTrcInst,tmpTrcInst2,sizeof(FrameInst)*length);
               memcpy(frameInst,tmpTrcInst,sizeof(FrameInst)*length);
               *LineCnt=length;
               *beginNo=frameInst[0].phisicalNo;
               *endNo= frameInst[*LineCnt-1].phisicalNo;
               instValid=TRUE;  instLen= *LineCnt;
               break;
               }  
           BeginFrameNo=tmpTrcInst[instLen-1].phisicalNo+1;
           length=*LineCnt; 
           readDirect=NULL;
           GetAsmForWin(FALSE,beginPos,endPos,length);
           ASSERT(*LineCnt>=length);
           if(length==0) { *LineCnt=0; endNo=beginNo; return FALSE; }
           memcpy(tmpTrcInst,tmpTrcInst2,sizeof(FrameInst)*length);
           memcpy(frameInst,tmpTrcInst,sizeof(FrameInst)*length);
           *LineCnt=length;
           *beginNo=frameInst[0].phisicalNo;
           *endNo= frameInst[*LineCnt-1].phisicalNo;
           instValid=TRUE;  instLen= *LineCnt;
           if(instLen==0) instValid=FALSE;
           break;           
           
     }//switch
    
  return TRUE;  
 }
               
//CSrcFile

/****************************************************************************
**
**  Name: CSrcFile::CSrcFile
**
**  Description:Construction of Class CSrcFile
**              You can modify m_nBuffers to a big value to save access time.
**
**  Parameters:
**     input:
**              
**
**     output:
**
**  Return data: 
****************************************************************************/
CSrcFile::CSrcFile():m_nBuffers(20), m_nRefInc(5), m_nAddLines(3)
{
    m_Buffer=new LineInfo[m_nBuffers];
    m_nUsedBufs=0;
}
   
CSrcFile::~CSrcFile()
{
int i;
    for(i=0; i<m_nUsedBufs; i++)
        if(m_Buffer[i].psrcline)
            delete m_Buffer[i].psrcline;
    delete m_Buffer;
    m_Buffer=NULL;
    m_nUsedBufs=0;
}

void CSrcFile::ClearData()
{
int i;
    for(i=0; i<m_nUsedBufs; i++)
        if(m_Buffer[i].psrcline)
            delete m_Buffer[i].psrcline;
    m_nUsedBufs=0;
}

void CSrcFile::ModifyRefer(int index)
{
    ASSERT(index>=0&&index<m_nUsedBufs);
int i, bak=m_Buffer[index].refertime;

    for(i=0; i<m_nUsedBufs; i++)
        if(m_Buffer[i].refertime>1)
            m_Buffer[i].refertime--;
    m_Buffer[index].refertime=min(10, bak+m_nRefInc);
}

void CSrcFile::Remove(int index)
{
    ASSERT(index>=0&&index<m_nUsedBufs);
int i;
    
    if(m_Buffer[index].psrcline)
    delete m_Buffer[index].psrcline;
    for(i=index; i<m_nUsedBufs-1; i++)
        m_Buffer[i]=m_Buffer[i+1];
    m_nUsedBufs--;
}

int CSrcFile::DelOld(void)
{
    ASSERT(m_nUsedBufs==m_nBuffers);
int i, min, minindex;

    for(i=0; i<m_nUsedBufs; i++)
        if(m_Buffer[i].refertime==0)
            Remove(i);
    if(m_nUsedBufs==m_nBuffers)
    {
        min=m_Buffer[0].refertime;
        minindex=0;
        for(i=1; i<m_nUsedBufs; i++)
            if(min>m_Buffer[i].refertime)
            {
                min=m_Buffer[i].refertime;
                minindex=i;
            }
        Remove(minindex);
    }
    return (m_nBuffers-m_nUsedBufs);
}

BOOL CSrcFile::AddNew(U32 module, UINT line)
{
int lines=min(m_nAddLines, m_nBuffers-m_nUsedBufs);
int result, i;
char    str[41], linebuf[256];
CString filename;
CStdioFile file;

    ASSERT(lines>0);
    result=SrcGetModuleName(module, (LPSTR)str);
    if(result!=0) 
        return FALSE;
    filename=SrcGetModuleFullName((const char *) str);
    if(""==filename)
        return FALSE;
    result=file.Open(filename,CFile::modeRead);
    if(!result)
        return FALSE;
    result=0;
    while(result<int(line))
    {
        if(!file.ReadString(linebuf, 256))
        {
            return FALSE;                   //end of file
        }
        result++;
    }
    m_Buffer[m_nUsedBufs].refertime=m_nRefInc;
    m_Buffer[m_nUsedBufs].module=module;
    m_Buffer[m_nUsedBufs].linenum=line;
    m_Buffer[m_nUsedBufs].psrcline=new char[strlen(linebuf)+1];
    strcpy(m_Buffer[m_nUsedBufs].psrcline, linebuf);
    m_nUsedBufs++;
    for(i=1; i<lines; i++)
    {
        if(!file.ReadString(linebuf, 256))
            return TRUE;
        m_Buffer[m_nUsedBufs].refertime=0;
        m_Buffer[m_nUsedBufs].module=module;
        m_Buffer[m_nUsedBufs].linenum=line+i;
        m_Buffer[m_nUsedBufs].psrcline=new char[strlen(linebuf)+1];
        strcpy(m_Buffer[m_nUsedBufs].psrcline, linebuf);
        m_nUsedBufs++;
    }
    return TRUE;
}

BOOL CSrcFile::GetIndex(U32 module, UINT line, int& index)
{
int i;

    for(i=0; i<m_nUsedBufs; i++)
    {
        if(m_Buffer[i].linenum==line&&m_Buffer[i].module==module)
        {
            index=i;
            ModifyRefer(i);
            return TRUE;
        }
    }
    return FALSE;
}

BOOL CSrcFile::GetALine(U32 openModule, UINT line , char * str)
{
int index;

	if(!GetIndex(openModule, line, index))
	{
		if(m_nUsedBufs==m_nBuffers)
			DelOld();
		if(!AddNew(openModule, line))
		{
			*str=NULL;
			return FALSE;
		}
		GetIndex(openModule, line, index);
	}
	strcpy(str, m_Buffer[index].psrcline);
	index=strlen(str);
	if(index)
		str[index-1]=NULL;
	return TRUE;
}

int TestKeyNoRemove(WORD wKey)
{   
    MSG msg;
    if(PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST,
        PM_NOREMOVE|PM_NOYIELD)) {
        if(msg.message == WM_KEYDOWN && msg.wParam == wKey) 
            return  1; 
        else 
        	PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST,
        PM_REMOVE/*|PM_NOYIELD*/);
                   
    }            
    return  0;
}

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