
/***************************************************************************
**
**    $Header:   D:/EPSLDV1/SRC/LOG/BPTSERVE.CPP   1.8   20 Jun 1996 09:24:04   ZJRD  $
**
**    $Log:   D:/EPSLDV1/SRC/LOG/BPTSERVE.CPP  $
** 
**    Rev 1.8   20 Jun 1996 09:24:04   ZJRD
** EasyPack/SLD Version 1.20a
** 
**    Rev 1.6   10 Jun 1996 10:18:44   ZJRD
** EasyPack/SLD Version 1.20
** 
**    Rev 1.4   29 May 1996 09:27:24   ZJRD
** No change.
** 
**    Rev 1.3   16 May 1996 08:59:04   ZJRD
** EasyPack/SLD Version 1.94
** 
**    Rev 1.2   10 May 1996 09:07:36   ZJRD
** No change.
** 
**    Rev 1.1   02 May 1996 10:22:06   ZJRD
** EasyPack/SLD Version 1.92
** 
**    Rev 1.31   18 Apr 1996 12:52:26   Shirley
** No change.
** 
**    Rev 1.30   12 Apr 1996 10:33:14   Shirley
** EasyPack/SLD Version 1.90
** 
**    Rev 1.28   15 Feb 1996 08:46:14   Shirley
** No change.
** 
**    Rev 1.27   12 Feb 1996 14:01:18   Shirley
** No change.
** 
**    Rev 1.26   06 Feb 1996 15:26:44   Shirley
** No change.
** 
**    Rev 1.25   06 Feb 1996 13:42:06   Shirley
** No change.
** 
**    Rev 1.24   01 Feb 1996 10:10:42   Shirley
** No change.
** 
**    Rev 1.23   26 Jan 1996 09:11:30   Shirley
** No change.
** 
**    Rev 1.22   25 Jan 1996 13:11:50   Shirley
** No change.
** 
**    Rev 1.21   24 Jan 1996 10:31:16   Shirley
** No change.
** 
**    Rev 1.20   23 Jan 1996 11:21:36   Shirley
** EasypPack/SLD Version 0.34c
** 
**    Rev 1.18   15 Jan 1996 16:09:48   Shirley
** EasyPack/SLD Version 0.34a
** 
**    Rev 1.16   30 Nov 1995 09:07:36   Shirley
** No change.
** 
**    Rev 1.15   28 Nov 1995 15:28:40   Shirley
** No change.
** 
**    Rev 1.14   21 Nov 1995 11:17:36   Shirley
** No change.
** 
**    Rev 1.13   13 Nov 1995 09:21:12   Shirley
** No change.
** 
**    Rev 1.12   12 Nov 1995 11:27:46   Shirley
** No change.
** 
**    Rev 1.11   08 Nov 1995 16:27:20   Shirley
** No change.
** 
**    Rev 1.10   08 Nov 1995 12:39:16   Shirley
** No change.
** 
**    Rev 1.9   02 Nov 1995 10:02:00   Shirley
** No change.
** 
**    Rev 1.8   27 Oct 1995 16:44:38   Shirley
** No change.
** 
**    Rev 1.7   27 Oct 1995 13:42:58   Shirley
** No change.
** 
**    Rev 1.6   25 Oct 1995 14:25:26   Shirley
** No change.
** 
**    Rev 1.5   18 Oct 1995 14:46:30   Shirley
** EasyPack/SLD Version 0.1e
** 
**    Rev 1.3   29 Sep 1995 09:47:50   Shirley
** No change.
** 
**    Rev 1.2   20 Sep 1995 10:56:20   Shirley
** EasyPack/SLD Version 0.1b
** 
**    Rev 1.1   15 Sep 1995 09:47:24   Shirley
** EasyPack/SLDV0.1a 
** 
**    Rev 1.0   07 Sep 1995 09:54:54   Shirley
** Initial revision.
**
****************************************************************************/

/***************************************************************************
**
** File name : BPTSERVE.CPP 
** Author:BRIGHT CHEN  ,  JOHN CHOW
** Description:
**
**
**    Finished date: 1995.9.1   V 0.1
**    UPDATE DATE :  1995.9.8   V 0.1A
**                 FIXED BUG 8 IN  ShowBptToShell();
**                 MODIFY THE AddBpt(unsigned short addr);
**                 MODIFY THE void BreakpointCmd(int nArgc, char* pszArgv[]);
**
**
**    Copyright (C) 1995 Microtek International, Inc.
**    All Rights Reserved
**
****************************************************************************/


////////////////////////////////
//bptserve.cpp
//Bright cheng
//95/4
//Chris Fang
//March, 96
////////////////////////////////
#include "stdafx.h"
#include "stdlib.h"
#include "string.h"
#include "ctype.h"

#include "abibase.h"
#include "bptserve.h"
#include "cpust.h"					//use getcpustatus
#include "hosterrs.h"				//error handle

#define ERRMSG (m_sErrmsg.GetBuffer(m_sErrmsg.GetLength()))

extern STATUS AbiSetBp(ADDR);
extern STATUS AbiClrBp(ADDR);
extern STATUS AbiClrAllBp();
//extern STATUS AbiGetBp(ADDR,ADDR,ADDR*);		//not use
extern void   ShowLine(char*);
extern int    TestKey(WORD);

static BptServer BptSrv;

//notes:in this function anything needing initiation about bpt
int InitBp(void)
{
	int i;
	unsigned char status;
	//init breakpoint        
	if(!GetCpuStatus(status))
		return FALSE;
	if(status==STATUS_GO)
	{
		ErrDisplayError(ER_GOFLY_ERR_MSG);
		return FALSE;
	}
	i = AbiClrAllBp();
	if(i!=ICE_OK)
	{
		ErrDisplayError(ER_ICE_OK+i);
		return FALSE;
	}
	return TRUE;  
}


void BreakpointCmd(int nArgc, char* pszArgv[])
{
unsigned short addr;
char*          stop_at;

    if(1==nArgc) 
      {
        BptSrv.ShowBptToShell();
        
       /* short num=0; unsigned short addr;                   
        BOOL reset;
        do {
        reset=BptGetOneBpt(num, &addr);
        char tmp[10];      
        wsprintf(tmp,"%X",addr);
        if(reset) ShowLine(tmp);
        num++;
          } while(reset);
          */
        }
    if(2==nArgc)
    {                               
        if('X' == toupper(pszArgv[1][0]))
         {
          ShowLine("Syntax error???");
          return;
          }
        if('P' == toupper(pszArgv[1][0]))
            addr = (unsigned short)strtoul(pszArgv[1]+2,&stop_at,16);
        else    
            addr = (unsigned short)strtoul(pszArgv[1],&stop_at,16);
        BptSrv.AddBptfromShell(addr);
    }
}

void ClearCmd(int /*nArgc*/, char* pszArgv[])
{
unsigned short addr;
char*          stop_at;

    CString str = strupr(pszArgv[1]);
    if(str=="ALL")
        BptSrv.ClrAllBptfromShell();
    else
    {
        if('P' == toupper(pszArgv[1][0]))
            addr = (unsigned short)strtoul(pszArgv[1]+2,&stop_at,16);
        else    
            addr = (unsigned short)strtoul(pszArgv[1],&stop_at,16);
        BptSrv.ClrOneBptfromShell(addr);
    }
}

BOOL BptEnableBpt(unsigned short addr)
{
 return BptSrv.EnableBpt(addr);
}


BOOL BptSearchBpt(unsigned short addr,BYTE &eFlag)
{                                                    
    //BYTE eFlag;
    return BptSrv.SearchBpt(addr,eFlag);
}


BOOL BptDisableBpt(unsigned short addr)
{
    return BptSrv.DisableBpt(addr);
}

BOOL BptGetOneBpt(short num, unsigned short *addr)
{
    return BptSrv.GetOneBpt(num, addr);
}

BOOL BptAddBptfromWnd(unsigned short addr)
{
    return BptSrv.BptAddBptfromWnd(addr);
}

BOOL BptClrOneBptfromWnd(unsigned short addr)
{
    return BptSrv.BptClrOneBptfromWnd(addr);
}

BOOL BptClrAllBptfromWnd(void)
{
    return BptSrv.BptClrAllBptfromWnd();
}                                       
                          
BOOL SaveBpt(const char * pFileName)
{                                                  
 return BptSrv.SaveBpt(pFileName);
 }
                                                  
BOOL RestoreBpt(const char * pFileName)
{                                                  
 return BptSrv.RestoreBpt(pFileName);
 }

void BptServer::AddBptfromShell(unsigned short addr)
{
ADDR   bpAddr;
unsigned char status;

    bpAddr.addrType = 1;
    bpAddr.addr = addr;

	if(!GetCpuStatus(status))
		return;
	if(status==STATUS_GO)
	{
		ErrGetErrorText(ER_GOFLY_ERR_MSG, m_sErrmsg);
		ShowLine(ERRMSG);
		return;
	}
    m_nErrorID = AbiSetBp(bpAddr);
    
    if(ICE_OK == m_nErrorID)
    {
        AddBpt(addr);        
        ShowLine("Breakpoint is set successfully.");
    }
    else
	{
		ErrGetErrorText(ER_ICE_OK+m_nErrorID, m_sErrmsg);
		ShowLine(ERRMSG);
	}	
}

void BptServer::ClrOneBptfromShell(unsigned short addr)
{
ADDR   bpAddr;
unsigned char status;

    bpAddr.addrType = 1;
    bpAddr.addr = addr;

	if(!GetCpuStatus(status))
		return;
	if(status==STATUS_GO)
	{
		ErrGetErrorText(ER_GOFLY_ERR_MSG, m_sErrmsg);
		ShowLine(ERRMSG);
		return;
	}
    m_nErrorID = AbiClrBp(bpAddr);
    if(ICE_OK == m_nErrorID)
    {
        ClrBpt(addr);
        ShowLine("Breakpoint is clear successfully.");
    }
    else
    {
        ErrGetErrorText(ER_ICE_OK+m_nErrorID, m_sErrmsg);
		ShowLine(ERRMSG);
	}	
}

void BptServer::ClrAllBptfromShell()
{
unsigned char status;

	if(!GetCpuStatus(status))
		return;
	if(status==STATUS_GO)
	{
		ErrGetErrorText(ER_GOFLY_ERR_MSG, m_sErrmsg);
		ShowLine(ERRMSG);
		return;
	}
    m_nErrorID = AbiClrAllBp();

    if(ICE_OK == m_nErrorID)
    {
        ClrAllBpt();
        ShowLine("Breakpoints are clear successfully.");
    }
    else
    {
		ErrGetErrorText(ER_ICE_OK+m_nErrorID, m_sErrmsg);
		ShowLine(ERRMSG);
	}
}

void BptServer::ShowBptToShell()
{
 char DisplayStr[48];
 BOOL hasBPT=FALSE;

 BPT_CHAIN* pTmpBpt = m_pFirstBpt;        
 while(NULL!=(pTmpBpt->pNextBpt))
  {
   wsprintf(DisplayStr,"Breakpoint at  %04X ",pTmpBpt->addr);
   strcat(DisplayStr,pTmpBpt->enableFlag? "Enabled " : "Disabled");
   ShowLine(DisplayStr);     
   hasBPT=TRUE;
   pTmpBpt = pTmpBpt->pNextBpt;
   }           
 if(!hasBPT)  ShowLine("No breakpoint is set!");
 }

BOOL BptServer::BptAddBptfromWnd(unsigned short addr)
{
ADDR   bpAddr;
unsigned char status;

    bpAddr.addrType = 1;
    bpAddr.addr = addr;

	if(!GetCpuStatus(status))
		return FALSE;
	if(status==STATUS_GO)
	{
		ErrDisplayError(ER_GOFLY_ERR_MSG);
		return FALSE;
	}
    m_nErrorID = AbiSetBp(bpAddr);

    if(ICE_OK == m_nErrorID)
    {
        AddBpt(addr);
        return(TRUE);
    }
    else    
    {
		ErrDisplayError(ER_ICE_OK+m_nErrorID);
        return(FALSE);
    }    
}

BOOL BptServer::BptClrOneBptfromWnd(unsigned short addr)
{
ADDR   bpAddr;
unsigned char status;

    bpAddr.addrType = 1;
    bpAddr.addr = addr;

	if(!GetCpuStatus(status))
		return FALSE;
	if(status==STATUS_GO)
	{
		ErrDisplayError(ER_GOFLY_ERR_MSG);
		return FALSE;
	}
    m_nErrorID = AbiClrBp(bpAddr);

    if(ICE_OK == m_nErrorID)
    {
        ClrBpt(addr);
        return(TRUE);
    }
    else
    {
        ErrDisplayError(ER_ICE_OK+m_nErrorID);
        return(FALSE);
    }
}

BOOL BptServer::BptClrAllBptfromWnd()
{
unsigned char status;

	if(!GetCpuStatus(status))
		return FALSE;
	if(status==STATUS_GO)
	{
		ErrDisplayError(ER_GOFLY_ERR_MSG);
		return FALSE;
	}
    m_nErrorID = AbiClrAllBp();

    if(ICE_OK == m_nErrorID)
    {
        ClrAllBpt();
        return(TRUE);
    }
    else
    {
        ErrDisplayError(ER_ICE_OK+m_nErrorID);
        return(FALSE);
    }
}

BOOL BptServer::EnableBpt(unsigned short addr)
{
unsigned char status;

    if(m_pFirstBpt->pNextBpt == NULL)
        return FALSE;
        
    ADDR   bpAddr;

    bpAddr.addrType = 1;
    bpAddr.addr = addr;
        
    BPT_CHAIN* pTmpBpt = m_pFirstBpt;        
        
    while(NULL!=(pTmpBpt->pNextBpt))
    {
        if(pTmpBpt->addr == addr)
		{
			if(!GetCpuStatus(status))
				return FALSE;
			if(status==STATUS_GO)
			{
				ErrDisplayError(ER_GOFLY_ERR_MSG);
				return FALSE;
			}
            m_nErrorID = AbiSetBp(bpAddr);
            if(ICE_OK == m_nErrorID)
            {
                pTmpBpt->enableFlag = 1;
                return TRUE;
            }
            else
            {
                ErrDisplayError(ER_ICE_OK+m_nErrorID);
                return FALSE;
            }
        }
        pTmpBpt = pTmpBpt->pNextBpt;
    }
    return FALSE;
}


BOOL BptServer::DisableBpt(unsigned short addr)
{
    if(m_pFirstBpt->pNextBpt == NULL)
        return FALSE;
        
    ADDR   bpAddr;
	unsigned char status;
	
    bpAddr.addrType = 1;
    bpAddr.addr = addr;
        
    BPT_CHAIN* pTmpBpt = m_pFirstBpt;        
        
    while(NULL!=(pTmpBpt->pNextBpt))
    {
        if(pTmpBpt->addr == addr)
        {
			if(!GetCpuStatus(status))
				return FALSE;
			if(status==STATUS_GO)
			{
				ErrDisplayError(ER_GOFLY_ERR_MSG);
				return FALSE;
			}
			m_nErrorID = AbiClrBp(bpAddr);
            if(ICE_OK == m_nErrorID)
            {
                pTmpBpt->enableFlag = 0;
                return TRUE;
            }
            else
            {
                ErrDisplayError(ER_ICE_OK+m_nErrorID);
                return FALSE;
            }
        }
        pTmpBpt = pTmpBpt->pNextBpt;
    }
    return FALSE;
}

void BptServer::AddBpt(unsigned short addr)
{
    BPT_CHAIN*  pNewBpt = m_pFirstBpt;
    while(NULL!=(pNewBpt->pNextBpt))
    {
        if(addr == pNewBpt->addr)
         { 
          pNewBpt->enableFlag = 1;
          return;
          }
        pNewBpt = pNewBpt->pNextBpt;
    }                 
    
    pNewBpt = new BPT_CHAIN;
    if(!pNewBpt)
    {
        AfxMessageBox("Insuffient memory!");
        return;
    }
    pNewBpt->addr = addr;
    pNewBpt->enableFlag = 1;
    pNewBpt->pNextBpt = m_pFirstBpt;
    m_pFirstBpt = pNewBpt;
}

void BptServer::ClrBpt(unsigned short addr)
{
    if(m_pFirstBpt->pNextBpt == NULL)
        return;
        
    BPT_CHAIN* pTmpBpt = m_pFirstBpt;        
    if(m_pFirstBpt->addr == addr)
    {
        m_pFirstBpt = m_pFirstBpt->pNextBpt;
        delete pTmpBpt;
        return;
    }
        
    BPT_CHAIN*  pClrBpt;
    while(NULL!=(pTmpBpt->pNextBpt->pNextBpt))
    {
        if(pTmpBpt->pNextBpt->addr == addr)
        {
            pClrBpt = pTmpBpt->pNextBpt;
            pTmpBpt->pNextBpt=pTmpBpt->pNextBpt->pNextBpt;
            delete pClrBpt;
            return;
        }
        pTmpBpt = pTmpBpt->pNextBpt;
    }
}

void BptServer::ClrAllBpt()
{
    if(m_pFirstBpt->pNextBpt == NULL)
        return;
        
    BPT_CHAIN* pTmpBpt;        
    while(NULL!=(m_pFirstBpt->pNextBpt))
    {
        pTmpBpt = m_pFirstBpt;
        m_pFirstBpt = m_pFirstBpt->pNextBpt;
        delete pTmpBpt;
    }
}

BOOL BptServer::SearchBpt(unsigned short addr,BYTE &eFlag)
{
    if(m_pFirstBpt->pNextBpt == NULL)
        return FALSE;
        
    BPT_CHAIN* pTmpBpt = m_pFirstBpt;        
        
    while(NULL!=(pTmpBpt->pNextBpt))
    {
        if(pTmpBpt->addr == addr)
        {
            eFlag=pTmpBpt->enableFlag;
            return TRUE;
        }
        pTmpBpt = pTmpBpt->pNextBpt;
    }
    return FALSE;
}

BOOL BptServer::GetOneBpt(short num, unsigned short *addr)
{
    long bptNum=0;
    
    BPT_CHAIN* pTmpBpt = m_pFirstBpt;        
    
    //get the number of breakpoints john 95.9
    while(pTmpBpt->pNextBpt != NULL)
     {             
      bptNum++;
      pTmpBpt = pTmpBpt->pNextBpt;
      }                        
    pTmpBpt = m_pFirstBpt;   
    //convert the index john 95.9
    if( num>=bptNum || num<0 ) return FALSE;
    num=(short)bptNum-(num+1);
        
    while(pTmpBpt->pNextBpt != NULL)
     {             
      if(num == 0) 
       {
        *addr = pTmpBpt->addr;
        return TRUE;          
        }
      num--;
      pTmpBpt = pTmpBpt->pNextBpt;
      }                
    
    return FALSE;
}
    
BOOL BptServer::SaveBpt(const char * pFileName)
{       
  CString fileBuf="ROGERANDJOHN";
  CFile saveFile;                   
  unsigned long num=0;
  //OPEN FILE
  CFileException e;
  if( !saveFile.Open( pFileName, CFile::modeCreate , &e) )
   {
    AfxMessageBox("BreakPoint Save File Create Error!");
    return FALSE;	
	}          
  saveFile.Close();           
  if( !saveFile.Open( pFileName, CFile::modeReadWrite, &e) )
   {
    AfxMessageBox("BreakPoint Save File Create Error!");
    return FALSE;	
	}           
  //WRITE MY FLAG
  saveFile.Write( fileBuf.GetBuffer(13),13);
  fileBuf.ReleaseBuffer();
  //write breakpoint number
  saveFile.Write(&num,sizeof(unsigned long));
  //write breakpoint
  BPT_CHAIN* pTmpBpt = m_pFirstBpt;        
  while(NULL!=(pTmpBpt->pNextBpt))
   {
     saveFile.Write(&(pTmpBpt->addr),sizeof(unsigned short));
     saveFile.Write(&(pTmpBpt->enableFlag),sizeof(BYTE));
     num++;
     pTmpBpt = pTmpBpt->pNextBpt;
     }
  //rewrite the number of breakpoint
  saveFile.SeekToBegin(); 
  saveFile.Read( fileBuf.GetBuffer(13),13);
  fileBuf.ReleaseBuffer(1);
  saveFile.Write(&num,sizeof(unsigned long));
  //close file
  saveFile.SeekToEnd(); 
  saveFile.Close();
  return TRUE;
 }
 
 
BOOL BptServer::RestoreBpt(const char * pFileName)
{ 
  CString fileBuf;
  CFile readFile; 
  unsigned char status;
  unsigned long num=0;

  	if(!GetCpuStatus(status))
		return FALSE;
	if(status==STATUS_GO)
	{
		ErrDisplayError(ER_GOFLY_ERR_MSG);
		return FALSE;
	}

  //OPEN FILE
  if( !readFile.Open( pFileName , CFile::modeRead) )
   {
    AfxMessageBox("BreakPoint File Open Error!");
    return FALSE;	
	}                 
  //read flag
  readFile.Read( fileBuf.GetBuffer(13),13);
  fileBuf.ReleaseBuffer();
  if(fileBuf!="ROGERANDJOHN")
   { 
    AfxMessageBox("Wrong Format of BreakPoint File!");
    readFile.Close();
    return FALSE;
    }
  //read number
  readFile.Read(&num,sizeof(unsigned long));	
  if(readFile.GetLength() < 13+sizeof(unsigned long)
                            +num*(sizeof(unsigned short)+sizeof(BYTE)) )
   { 
    AfxMessageBox("Wrong Format of BreakPoint File!");
    readFile.Close();
    return FALSE;
    }                       
  //clear current breakpoint 
  if(ICE_OK!=AbiClrAllBp())
   {                   
    AfxMessageBox("ABI Clear All BreakPoint Error!");
    readFile.Close();
    return FALSE;
    }
  ClrAllBpt();  //soft clear
  ASSERT(m_pFirstBpt->pNextBpt==NULL);
  //read and set breakpoint from file 
  if(num==0) return TRUE;
  unsigned short tmpAddr;
  BYTE tmpEnableFlag;
  for(unsigned long i=0;i<num;i++)
   { 
    LONG tmpFilePoint=13+sizeof(unsigned long)+
                             (sizeof(unsigned short)+sizeof(BYTE))*(num-1-i);
    readFile.Seek(tmpFilePoint,CFile::begin);
    readFile.Read(&(tmpAddr),sizeof(unsigned short));
    readFile.Read(&(tmpEnableFlag),sizeof(BYTE));
    
    if(tmpEnableFlag)
    {                        
     ADDR   bpAddr;
     bpAddr.addrType = 1;
     bpAddr.addr = tmpAddr;
	m_nErrorID=AbiSetBp(bpAddr);
     if(ICE_OK!=m_nErrorID)
      {        
       ErrDisplayError(ER_ICE_OK+m_nErrorID);
       readFile.Close();
       return FALSE;
       }
     }//IF
    
    BPT_CHAIN*  pNewBpt = m_pFirstBpt;
    while(NULL!=(pNewBpt->pNextBpt))
     {
        if(tmpAddr == pNewBpt->addr)
         {
          AfxMessageBox("Internal Error! Call Your Vendor!");
          readFile.Close();
          return FALSE;
          }
        pNewBpt = pNewBpt->pNextBpt;
      }                 
    
    pNewBpt = new BPT_CHAIN;
    if(!pNewBpt)
     {
        AfxMessageBox("Insuffient memory!");
        readFile.Close();
        return FALSE;
      }
    pNewBpt->addr = tmpAddr;
    pNewBpt->enableFlag = tmpEnableFlag;
    pNewBpt->pNextBpt = m_pFirstBpt;
    m_pFirstBpt = pNewBpt;                           
    
    }//FOR 
  readFile.Close();  
  return TRUE;  
 }

BOOL RecoverBP(void)
{
	return (BptSrv.RecoverBP());
}                               

BOOL BptServer::RecoverBP(void)
{
BPT_CHAIN*	pTemp=m_pFirstBpt;
BOOL		retcode=TRUE;
ADDR   		bpAddr;
unsigned char status;

	if(!GetCpuStatus(status))
		return FALSE;
	if(status==STATUS_GO)
	{
		ErrDisplayError(ER_GOFLY_ERR_MSG);
		return FALSE;
	}	
	if(ICE_OK!=AbiClrAllBp())
		retcode=FALSE;

//Bpt chain: single direct, and last node is a dummy data.	
	while(pTemp->pNextBpt)
	{
		if(pTemp->enableFlag)
		{
     		bpAddr.addrType = 1;
     		bpAddr.addr = pTemp->addr;
			
     		if(ICE_OK!=AbiSetBp(bpAddr))
     		{
     			retcode=FALSE;
     		}	
		}
		pTemp=pTemp->pNextBpt;
	}
	return retcode;	
}

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