
/***************************************************************************
**
**    $Header:   D:/ECB2S/SRC/LOG/EMUSTEP.CPP   1.2.1.5   17 Apr 1997 15:48:46   ZJRD  $
**
**    $Log:   D:/ECB2S/SRC/LOG/EMUSTEP.CPP  $
** 
**    Rev 1.2.1.5   17 Apr 1997 15:48:46   ZJRD
** No change.
** 
**    Rev 1.2.1.4   16 Apr 1997 10:20:06   ZJRD
** No change.
** 
**    Rev 1.2.1.3   10 Apr 1997 15:31:28   ZJRD
** 2.09F
** 
**    Rev 1.2.1.1   03 Apr 1997 15:12:16   ZJRD
** No change.
** 
**    Rev 1.2.1.0   28 Mar 1997 10:17:18   ZJRD
** easy pack sld 2.09d
** 
**    Rev 1.1   19 Mar 1997 11:28:24   ZJRD
** Easy Pack SLD 2.09c
** 
**    Rev 1.0   12 Mar 1997 14:46:08   ZJRD
** Initial revision.
** 
**    Rev 1.7.1.0.1.2   09 Dec 1996 10:17:44   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:24   ZJRD
** No change.
** 
**    Rev 1.7.1.3   05 Sep 1996 11:33:50   ZJRD
** No change.
** 
**    Rev 1.7.1.2   02 Sep 1996 10:00:54   ZJRD
** No change.
** 
**    Rev 1.7.1.1   28 Aug 1996 15:44:12   ZJRD
** No change.
** 
**    Rev 1.7.1.0   12 Aug 1996 10:49:32   ZJRD
** EasyPack/SLD Version 1.98
** 
**    Rev 1.5   05 Jun 1996 14:51:44   ZJRD
** EasyPack/SLD Version 1.96
** 
**    Rev 1.4   29 May 1996 09:33:14   ZJRD
** No change.
** 
**    Rev 1.3   16 May 1996 09:05:20   ZJRD
** No change.
** 
**    Rev 1.2   10 May 1996 09:11:22   ZJRD
** No change.
** 
**    Rev 1.1   02 May 1996 10:23:14   ZJRD
** EasyPack/SLD Version 1.92
** 
**    Rev 1.31   18 Apr 1996 12:56:54   Shirley
** EasyPack/SLD Version 1.91
** 
**    Rev 1.30   12 Apr 1996 10:42:18   Shirley
** EasyPack/SLD Version 1.90
** 
**    Rev 1.28   15 Feb 1996 08:50:20   Shirley
** No change.
** 
**    Rev 1.27   12 Feb 1996 14:06:30   Shirley
** No change.
** 
**    Rev 1.26   06 Feb 1996 15:33:00   Shirley
** No change.
** 
**    Rev 1.25   06 Feb 1996 13:47:16   Shirley
** No change.
** 
**    Rev 1.24   01 Feb 1996 10:13:50   Shirley
** No change.
** 
**    Rev 1.23   26 Jan 1996 09:18:02   Shirley
** No change.
** 
**    Rev 1.22   25 Jan 1996 13:17:58   Shirley
** EasyPack/SLD Version 0.35
** 
**    Rev 1.21   24 Jan 1996 10:33:44   Shirley
** EasyPack/SLD Version 0.34d
** 
**    Rev 1.20   23 Jan 1996 11:22:34   Shirley
** EasypPack/SLD Version 0.34c
** 
**    Rev 1.19   18 Jan 1996 10:13:34   Shirley
** No change.
** 
**    Rev 1.18   15 Jan 1996 16:15:04   Shirley
** EasyPack/SLD Version 0.34a
** 
**    Rev 1.17   04 Jan 1996 11:08:52   Shirley
** No change.
** 
**    Rev 1.16   30 Nov 1995 09:11:34   Shirley
** No change.
** 
**    Rev 1.15   28 Nov 1995 15:32:12   Shirley
** No change.
** 
**    Rev 1.14   21 Nov 1995 11:22:42   Shirley
** No change.
** 
**    Rev 1.13   13 Nov 1995 09:28:02   Shirley
** EasyPack/SLD Version 0.30
** 
**    Rev 1.12   12 Nov 1995 11:29:50   Shirley
** No change.
** 
**    Rev 1.11   08 Nov 1995 16:31:40   Shirley
** No change.
** 
**    Rev 1.10   08 Nov 1995 12:40:14   Shirley
** No change.
** 
**    Rev 1.9   02 Nov 1995 10:07:32   Shirley
** No change.
** 
**    Rev 1.8   27 Oct 1995 16:50:44   Shirley
** No change.
** 
**    Rev 1.7   27 Oct 1995 13:47:06   Shirley
** No change.
** 
**    Rev 1.6   25 Oct 1995 14:30:04   Shirley
** No change.
** 
**    Rev 1.5   18 Oct 1995 14:48:36   Shirley
** No change.
** 
**    Rev 1.4   13 Oct 1995 13:23:32   Shirley
** EasyPack/SLD Version 0.1d
** 
**    Rev 1.3   29 Sep 1995 09:50:02   Shirley
** EasyPack/SLD Version 0.1c
** 
**    Rev 1.2   20 Sep 1995 10:54:14   Shirley
** No change.
** 
**    Rev 1.1   15 Sep 1995 09:45:40   Shirley
** EasyPack/SLDV0.1a 
** 
**    Rev 1.0   07 Sep 1995 09:55:44   Shirley
** Initial revision.
**
****************************************************************************/

/////////////////////////////////////////////////////////////////////////////
//
//  File name: EMUSTEP.CPP
//
//  Description: The implementation file for the class: CEmulationStep.
//
//  Author: Chen Jun
//
//  Date: 05/06/95
//
//  Modification:
//      1. 05/06/95, Initial version of the class: CEmulationStep.
//      2. 05/10/95, Initial version of the command: STEPOption.
//      3. 10/10/95, Remove Stepoption command.
//
/////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////
// Include files.
#include "stdafx.h"
#include "resource.h"

#include "cpucom.h"
#include "uicom.h"
                     
#include "symbscty.h"                     
#include "emustep.h"                           
#include "cpust.h"
#include "errcodec.h"
#include "mainfrm.h"
#include "address.h"
#include "addrapi.h"

/////////////////////////////////////////////////////////////////////////////
// Debug flags.
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// Type definitions.


/////////////////////////////////////////////////////////////////////////////
// Macro definitions.


/////////////////////////////////////////////////////////////////////////////
// Global variables.
// int nStepOption;


/////////////////////////////////////////////////////////////////////////////
// Static variables.


/////////////////////////////////////////////////////////////////////////////
// External variables.
extern int GetPCBank(void);
extern STATUS SetPCBank(int);

/////////////////////////////////////////////////////////////////////////////
// Global function prototypes.
void StepCmd(int nArgc, char* pszArgv[]);
void StepoptionCmd(int nArgc, char* pszArgv);
void EmuServerStep(long lCount);
void EmuServerStepOver(long lCount);


/////////////////////////////////////////////////////////////////////////////
// Local function prototypes.


/////////////////////////////////////////////////////////////////////////////
// External function prototypes.
unsigned char TRCGetInstLen(unsigned char code);
int TRCGetInst(unsigned short BRIGHTAddr, unsigned char *BRIGHTCode,
               unsigned char len, unsigned char *BRIGHTResult);

#ifndef _SERVER_NO_ABI
    STATUS AbiGetOneReg(int iRegId, UINT* uRegValue);
    STATUS AbiSetReg(int iRegId, UINT uRegValue);
    STATUS AbiStepOne();
    STATUS AbiStepOver();
    STATUS AbiStepRange(ADDR stAddr, ADDR endAddr);
    STATUS AbiStepOverRange(ADDR stAddr, ADDR endAddr);
    STATUS AbiGetMemN(ADDR addr1, ADDR addr2, char* pchBuff);
#endif  // _SERVER_NO_ABI
                      
extern void ErrShow(U32 errorCode,BOOL bUI);                      
extern STATUS EmuSetTempBp(int nBank,unsigned short uAddr);
extern STATUS EmuClrTempBp();

extern "C" {
    extern int GetLineRange(int nBank,unsigned short uAddr, 
        unsigned short& uStart, unsigned short& uEnd);
    extern int GetStatementRange(int nBank,unsigned short uAddr, 
        unsigned short& uStart, unsigned short& uEnd);
    extern BOOL IsLibFunction(int nBank,unsigned short uAddr);
}
extern int GetLibRange(int nBank, unsigned short uAddr, 
    unsigned short& uStart, unsigned short& uEnd);

void SetStepOption(int nStepOption);
int GetStepOption(void);
//97.1 to support bank switch step
extern BOOL LdrBankFuncAddr(ADDR&,ADDR&); 

/////////////////////////////////////////////////////////////////////////////
// Executable codes.

/////////////////////////////////////////////////////////////////////////////
// Public functions.

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   StepCmd().
//
//  Description: The main control routine of Step command.
//
//  Input:  nArgc - Number of input parameters.
//          pszArgv - Input parameters.
//
//  Output: None.
//
//  Return: None.
//
/////////////////////////////////////////////////////////////////////////////
void StepCmd(int nArgc, char* pszArgv[])
{
    // Assertion of the input parameters.
    ASSERT( nArgc >= 1 && nArgc <= 6 );
    for ( int i = 0; i < nArgc; i++ ) {
        ASSERT( pszArgv[i] );
    }
    
    // Execute Step command.
    CEmulationStep* pEmulationStep = new CEmulationStep;
    if ( !pEmulationStep ) {                
        ::ErrShow(ER_EMU_INSUFFICIENT_MEMORY,TRUE);
        ASSERT( FALSE );
        return;
    }
    else {
        pEmulationStep->StepAction(nArgc, pszArgv);
        delete pEmulationStep;
    }

//    CEmulationStep objStep;
//    objStep.StepAction(nArgc, pszArgv);

}   // End of StepCmd().


// Step [count] server for the Source window.
void EmuServerStep(long lCount)
{
    // Assertion of the input parameters.
    ASSERT( lCount >= -4 && lCount <= 0xFFFF );
    // lCount:   1 <= lCount <= 0xFFFF - Count
    //           0 - Continuously
    //          -1 - Till Call
    //          -2 - Till Ret
    //          -3 - Into Call
    //          -4 - Over Ret

    // Step server.
    CEmulationStep* pEmulationStep = new CEmulationStep;
    if ( !pEmulationStep ) {
    	::ErrShow(ER_EMU_INSUFFICIENT_MEMORY,TRUE);
        ASSERT( FALSE );
        return;
    }
    else {
        pEmulationStep->EmuServerStep(lCount);
        delete pEmulationStep;
    }

}   // End of EmuServerStep().


// Step Over [count] server for the Source window.
void EmuServerStepOver(long lCount)
{
    // Assertion of the input parameters.
    ASSERT( lCount >= -4 && lCount <= 0xFFFF );
    // lCount:   1 <= lCount <= 0xFFFF - Count
    //           0 - Continuously
    //          -1 - Till Call
    //          -2 - Till Ret
    //          -3 - Into Call
    //          -4 - Over Ret

    // Step Over server.
    CEmulationStep* pEmulationStep = new CEmulationStep;
    if ( !pEmulationStep ) {                   
        ::ErrShow(ER_EMU_INSUFFICIENT_MEMORY,TRUE);
        ASSERT( FALSE );
        return;
    }
    else {
        pEmulationStep->EmuServerStepOver(lCount);
        delete pEmulationStep;
    }

}   // End of EmuServerStepOver().


/////////////////////////////////////////////////////////////////////////////
//
//  Name:   StepoptionCmd().
//
//  Description: The main control routine of Stepoption command.
//
//  Input:  nArgc - Number of input parameters.
//          pszArgv - Input parameters.
//
//  Output: None.
//
//  Return: None.
//
/////////////////////////////////////////////////////////////////////////////
void StepoptionCmd(int nArgc, char* pszArgv[])
{
    // Assertion of the input parameters.
    ASSERT( nArgc >= 1 && nArgc <= 2 );
    for ( int i = 0; i < nArgc; i++ ) {
        ASSERT( pszArgv[i] );
    }
    
    // Execute Stepoption command.
    CEmulationStep* pEmulationStepOption = new CEmulationStep;
    if ( !pEmulationStepOption ) {
        ::ErrShow(ER_EMU_INSUFFICIENT_MEMORY,TRUE);
        ASSERT( FALSE );
        return;
    }
    else {
        pEmulationStepOption->StepOptionAction(nArgc, pszArgv);
        delete pEmulationStepOption;
    }

//    CEmulationStep objStep;
//    objStep.StepOptionAction(nArgc, pszArgv);

}   // End of StepoptionCmd().



/////////////////////////////////////////////////////////////////////////////
// Implementation codes of class: CEmulationStep.

// Construction.
CEmulationStep::CEmulationStep()
{
    // Assertion of the input parameters.
    
    // Initial.
    m_isStepOver = FALSE;
    m_isStepForever = FALSE;
    m_isStepCount = FALSE;
    m_isTillCall = FALSE;
    m_isTillRet = FALSE;
    m_isAddr = FALSE;
    m_isRegMatch = FALSE;
    m_isMemMatch = FALSE;
    m_isIntoCall = FALSE;
    m_isOverRet = FALSE;

    m_uStepCount = 0;

//    ASSERT( ::nStepOption >= 0 && ::nStepOption <= 2 );
//    m_nStepOption = ::nStepOption;
    m_nStepOption = ::GetStepOption();
    ASSERT( m_nStepOption >= INSTRUCTION && m_nStepOption <= LINE );
    
}   // End of CEmulationStep::CEmulationStep().


// Destruction.
CEmulationStep::~CEmulationStep()
{
    // Assertion of the input parameters.
    
}   // End of CEmulationStep::~CEmulationStep().


// Emulation STEPOption command.
void CEmulationStep::StepOptionAction(int nArgc, char* pszArgv[])
{
    // Assertion of the input parameters.
    ASSERT( 1 == nArgc || 2 == nArgc );
    for ( int i = 0; i < nArgc; i++ ) {
        ASSERT( pszArgv[i] );
    }

    // Set the parameters.
    switch ( nArgc ) {
        case 1:
            break;
        case 2:
            if ( 0 == stricmp(pszArgv[1], "INSTRUCTION") ) {
                m_nStepOption = INSTRUCTION;
            }
            else if ( 0 == stricmp(pszArgv[1], "STATEMENT") ) {
                m_nStepOption = STATEMENT;
            }
            else if ( 0 == stricmp(pszArgv[1], "LINE") ) {
                m_nStepOption = LINE;
            }
            else {
                ASSERT( FALSE );
            }
            break;
        default:
            ASSERT( FALSE );
            break;
    }
    
    // Call the STEPOption kernel.
    StepOptionKernel();

}   // End of CEmulationStep::StepOptionAction().


// Stepoption kernel routine.  
// no use
void CEmulationStep::StepOptionKernel(void)
{
    // Assertion of the input parameters.
    //john 96.3
    if(GetXviewAppJohn()->m_nCpuStatus == STATUS_GO ) {
        if ( !m_isServer ) ::ErrShow(ER_GOFLY_ERR_MSG,FALSE);
       		else ::ErrShow(ER_GOFLY_ERR_MSG,TRUE);
        return;                    
    }
    
    // Set the global variable.
//    ::nStepOption = m_nStepOption;
    ::SetStepOption(m_nStepOption);
    
    // Set the global variable.
    m_nStepOption = ::GetStepOption();
    ASSERT( m_nStepOption >= INSTRUCTION && m_nStepOption <= LINE );

    // Display the current Step Option.
    char* pszOption[] = {
        "INSTRUCTION",
        "STATEMENT",
        "LINE"
    };
    wsprintf(m_pszResult, "Step option is: %s.", pszOption[m_nStepOption]);
    ShowLine(m_pszResult);
    
}   // End of CEmulationStep::StepOptionKernel().



// Emulation Step command.
void CEmulationStep::StepAction(int nArgc, char* pszArgv[])
{
    // Assertion of the input parameters.
    ASSERT( nArgc >= 1 && nArgc <= 6 );
    for ( int i = 0; i < nArgc; i++ ) {
        ASSERT( pszArgv[i] );
    }

    // Set the parameters.
    switch ( nArgc ) {
        case 1:
            // Step
            m_isStepCount = TRUE;
            m_uInputCount = 1;
            break;
        case 2:
            if ( 0 == stricmp(pszArgv[1], "OVER") ) {
                // Step Over
                m_isStepOver = TRUE;
                m_isStepCount = TRUE;
                m_uInputCount = 1;
            }
            else if ( 0 == stricmp(pszArgv[1], "FOREVER") ) {
                // Step Forever
                m_isStepForever = TRUE;
            }
            else {
                // Step count
                m_isStepCount = TRUE;
                StrToVar(pszArgv[1]);
                m_uInputCount = (unsigned short)m_ulVar;
            }
            break;
        case 3:
            if ( 0 == stricmp(pszArgv[1], "OVER") ) {
                m_isStepOver = TRUE;
                if ( 0 == stricmp(pszArgv[2], "FOREVER") ) {
                    // Step Over Forever
                    m_isStepForever = TRUE;
                }
                else {
                    // Step Over count
                    m_isStepCount = TRUE;
                    StrToVar(pszArgv[2]);
                    m_uInputCount = (unsigned short)m_ulVar;
                }
            }
            else if ( 0 == stricmp(pszArgv[1], "TILL") ) {
                if ( 0 == stricmp(pszArgv[2], "RET") ) {
                    // Step Till Ret
                    m_isTillRet = TRUE;
                }
                else {
                    // Step Till Call
                    m_isTillCall = TRUE;
                }
            }
            else {
                // Step adr1 adr2
                m_isAddr = TRUE;
                SetAddrVar(pszArgv[1], m_FromAddr);
                SetAddrVar(pszArgv[2], m_TillAddr);
            }
            break;
        case 4:
            m_isStepOver = TRUE;
            if ( 0 == stricmp(pszArgv[2], "TILL") ) {
                if ( 0 == stricmp(pszArgv[3], "RET") ) {
                    // Step Over Till Ret
                    m_isTillRet = TRUE;
                }
                else {
                    // Step Over Till Call
                    m_isTillCall = TRUE;
                }
            }
            else {
                // Step Over adr1 adr2
                m_isAddr = TRUE;
                SetAddrVar(pszArgv[2], m_FromAddr);
                SetAddrVar(pszArgv[3], m_TillAddr);
            }
            break;
        case 5:
            if ( '@' == pszArgv[2][0] ) {
                // Step Till @reg = value
                m_isRegMatch = TRUE;
                for ( int i = 0; i < ::nMaxReg; i++ ) {
                    if ( 0 == stricmp(pszArgv[2]+1, ::RegName[i]) ) {
                        m_nRegID = i;
                        break;
                    }
                }
                ASSERT( m_nRegID >= 0 && m_nRegID < nMaxReg );
                StrToVar(pszArgv[4]);
                m_uRegData = (unsigned int)m_ulVar;
            }
            else {
                // Step Till adr = value
                m_isMemMatch = TRUE;
                SetAddrVar(pszArgv[2], m_MatchAddr);
                StrToVar(pszArgv[4]);
                m_uchMemData = (unsigned char)m_ulVar;
            }
            break;
        case 6:
            m_isStepOver = TRUE;
            if ( '@' == pszArgv[3][0] ) {
                // Step Over Till @reg = value
                m_isRegMatch = TRUE;
                for ( int i = 0; i < ::nMaxReg; i++ ) {
                    if ( 0 == stricmp(pszArgv[3]+1, ::RegName[i]) ) {
                        m_nRegID = i;
                        break;
                    }
                }
                ASSERT( m_nRegID >= 0 && m_nRegID < nMaxReg );
                StrToVar(pszArgv[5]);
                m_uRegData = (unsigned int)m_ulVar;
            }
            else {
                // Step Over Till adr = value
                m_isMemMatch = TRUE;
                SetAddrVar(pszArgv[3], m_MatchAddr);
                StrToVar(pszArgv[5]);
                m_uchMemData = (unsigned char)m_ulVar;
            }
            break;
        default:
            ASSERT( FALSE );
            break;
    }
    
    // Call the Step kernel.
    if ( m_isStepCount ) {
        StepKernel();
    }
    else {
        StepKernel();
    }

}   // End of CEmulationStep::StepAction().

BOOL CEmulationStep::isCallBankSwitch(DWORD dwPC)
{    
	return (dwPC==m_adrBankCall.addr);
}

//no use                              
BOOL CEmulationStep::isCallBankSwitchNext(DWORD dwPC)
{ 
	 // Get the special address memory.
	 // Get current PC.
    unsigned int uRegValue;
    m_nErrorID = AbiGetOneReg(0, &uRegValue);
    if ( ICE_OK != m_nErrorID ) {
        DisplayErrorMessage();
        return (FALSE);
    } 
	 
    BYTE pchData[5];
    m_TestAddr.m_uAddr = (unsigned short)uRegValue;
    m_TestAddr.m_uchType = (unsigned char)GetPCBank();
    m_nErrorID = AbiGetMemN((ADDR&)m_TestAddr, (ADDR&)(m_TestAddr+3), (char*)pchData);
    if ( ICE_OK != m_nErrorID ) {
        DisplayErrorMessage();
        return (FALSE);
    }             
    
    if(pchData[0] != 0x12) return FALSE;
    
    WORD wTmp = 256*pchData[1] + pchData[2];
    return (wTmp == m_adrBankCall.addr);
}
 
BOOL CEmulationStep::isRetBankSwitch(DWORD dwPC)
{                    
	return (dwPC==m_adrBankRet.addr);
}

//97.2 for go till return 
BOOL CEmulationStep::isRetBankSwitchNext(DWORD dwPC)
{    
	 // Get the special address memory.
    BYTE pchData[5];
    m_TestAddr.m_uAddr = (unsigned short)dwPC;
    m_TestAddr.m_uchType = (unsigned char)GetPCBank();
    m_nErrorID = AbiGetMemN((ADDR&)m_TestAddr, (ADDR&)(m_TestAddr+3), (char*)pchData);
    if ( ICE_OK != m_nErrorID ) {
        DisplayErrorMessage();
        return (FALSE);
    }             
    
    if(pchData[0] != 0x02) return FALSE;
    
    WORD wTmp = 256*pchData[1] + pchData[2];
    return (wTmp == m_adrBankRet.addr);
	
}

 
void CEmulationStep::StepTillSource()
{ 
	 do {
		m_nErrorID = AbiStepOver();
        if ( ICE_OK != m_nErrorID ) {
            DisplayErrorMessage();
            return;
        } 
        // ESC to cancel Step process.
        if ( EscapeAbort() ) {
            return;
        }
	} while (!inSource());      
}

void CEmulationStep::StepTillSourceOne()
{ 
	do {
		m_nErrorID = AbiStepOne();
        if ( ICE_OK != m_nErrorID ) {
            DisplayErrorMessage();
            return;
        }
        // ESC to cancel Step process.
        if ( EscapeAbort() ) {
            return;
        }
	} while (!inSource());
}
                                  
//97.2 to fix go till return 
void CEmulationStep::StepTillSource2()
{ 
	 while (!inSource()) {
		m_nErrorID = AbiStepOver();
        if ( ICE_OK != m_nErrorID ) {
            DisplayErrorMessage();
            return;
        } 
        // ESC to cancel Step process.
        if ( EscapeAbort() ) {
            return;
        }
	} 
}
 

// Step kernel routine.
// AbiStepOne() & AbiStepOver().
void CEmulationStep::StepKernel(void)
{
    // Assertion of the input parameters.
    if(!LdrBankFuncAddr(m_adrBankCall,m_adrBankRet)) {
    	m_adrBankCall.addr = 0xffff;
    	m_adrBankRet.addr = 0xffff; 	
    }
    //john 96.3
    if(GetXviewAppJohn()->m_nCpuStatus == STATUS_GO ) {
        if ( !m_isServer ) ::ErrShow(ER_GOFLY_ERR_MSG,FALSE);
       		else ::ErrShow(ER_GOFLY_ERR_MSG,TRUE);
        return;                    
    }
    // Get the source line range.   
    m_nStepOption = ::GetStepOption();
    unsigned short uStart, uEnd;
    int nBank;
    if ( LINE == m_nStepOption || STATEMENT == m_nStepOption ) {
        GetStepRange(nBank,uStart, uEnd);
        if ( ICE_OK != m_nErrorID ) {
            return;
        }
    }

    // The Step loop.
    BOOL isStepAgain = FALSE;

    do {
        // High level Step range detection.
        if ( LINE == m_nStepOption || STATEMENT == m_nStepOption ) {
            if ( !m_isStepOver ) {
                // Step.
                ///////////////
                if ( StepMatchCall() ) {
                    // Is match CALL?
                    if ( IsLibFunction(m_TestAddr.m_uchType,m_TestAddr.m_uAddr) ) {
                        // Frank support to fix EP-RUNNING.
                        ::EmuSetTempBp(m_nBpAddrBank,m_uBpAddr);

                        // Skip the bank switch library function calling.
                        if(g_nBankNum == 0) {
	                    	m_nErrorID = AbiStepOver();
			                if ( ICE_OK != m_nErrorID ) {
			                    DisplayErrorMessage();
			                    return;
			                }                
			            } 
			            else StepTillSourceOne();
                        
                        // Frank support to fix EP-RUNNING.
                        ::EmuClrTempBp();
                    }
                    else {
                    	m_nErrorID = AbiStepOne();
                    }
                }
                else {
	            	// Added by Chen, 03/05/97
	                if ( g_nBankNum && StepMatchRet() ) {
	                	StepTillSource();
	        			if ( m_isOverRet ) {
	        				break;
						}
	                }
	                else {
                    	m_nErrorID = AbiStepOne();
                    }
                }
            }
            else {
                // Frank support to fix EP-RUNNING.
                ::EmuSetTempBp(m_nBpAddrBank,m_uBpAddr);

            	// Added by Chen, 03/05/97
                if ( g_nBankNum && StepMatchRet() ) {
                	StepTillSource();
        			if ( m_isOverRet ) {
        				break;
					}
                }
                else {
	                // Step Over.
	                m_nErrorID = AbiStepOver();
	            }

                // Frank support to fix EP-RUNNING.
                ::EmuClrTempBp();
            }
        }
        else {
            // Low level Step instruction.
            if ( !m_isStepOver ) {
                m_nErrorID = AbiStepOne();
            }
            else {
                m_nErrorID = AbiStepOver();
            }
            // Mixed or Assemble mode.
            m_uStepCount++;
        }

        // Detect ABI error.
        if ( ICE_OK != m_nErrorID ) {
		    if(m_nErrorID == ICE_EP_RUNNING && GetXviewAppJohn()->m_nCpuStatus != STATUS_GO) {
		    	GetXviewAppJohn()->m_nCpuStatus = STATUS_GO;
			    ((CMainFrame*)(GetXviewAppJohn()->m_pMainWnd))->m_wndStatusBar.UpdateStatusBar(2, "Running");
		    }

	    	DisplayErrorMessage();
		    return;                                               
        }

        // ESC to cancel Step process.
        if ( EscapeAbort() ) {
            return;
        }
        
        // Step again?
        if ( m_isStepForever ) {
            // Step [Over] Forever.
            if ( LINE == m_nStepOption || STATEMENT == m_nStepOption ) {
                // Get the current PC.
                unsigned int uPC;
                m_nErrorID = AbiGetOneReg(0, &uPC);
                if ( ICE_OK != m_nErrorID ) {
                    DisplayErrorMessage();
                    return;
                }                   
                //added 97.1 for bank switch
                if( g_nBankNum && (isCallBankSwitch(uPC)||isRetBankSwitch(uPC))) 
                	StepTillSource();
                	
                m_nErrorID = AbiGetOneReg(0, &uPC);
                if ( ICE_OK != m_nErrorID ) {
                    DisplayErrorMessage();
                    return;
                }
                ///////////////
                if ( uPC < uStart || uPC > uEnd || nBank!=GetPCBank() ) {
                	// Added by Chen, 03/13/97, to fix 320 movx..
                	if ( !inSource() ) {
                		StepTillSource();
                	}
                    // Update windows.
                    UpdateAllWindows();
                    // Get step range.
                    GetStepRange(nBank,uStart,uEnd);
                    if ( ICE_OK != m_nErrorID ) {
                        return;
                    }
                }
            }
            else {
                // Update windows: Low level.
                UpdateAllWindows();
            }
            isStepAgain = TRUE;
        }
        else if ( m_isStepCount ) {
            // Step [Over] count.
            if ( LINE == m_nStepOption || STATEMENT == m_nStepOption ) {
                // Get the current PC.
                unsigned int uPC;
                m_nErrorID = AbiGetOneReg(0, &uPC);
                if ( ICE_OK != m_nErrorID ) {
                    DisplayErrorMessage();
                    return;
                }     
                	//added 97.1 for bank switch
                if( g_nBankNum && (isCallBankSwitch(uPC)||isRetBankSwitch(uPC))) 
                	StepTillSource();
                m_nErrorID = AbiGetOneReg(0, &uPC);
                if ( ICE_OK != m_nErrorID ) {
                    DisplayErrorMessage();
                    return;
                }	                            
                ////////////////////
                if ( uPC < uStart || uPC > uEnd || nBank!=GetPCBank()) {
                	// Added by Chen, 03/13/97, to fix 320 movx..
                	if ( !inSource() ) {
                		StepTillSource();
                	}
                    m_uStepCount++;
                    // Get step range.
                    GetStepRange(nBank,uStart, uEnd);
                    if ( ICE_OK != m_nErrorID ) {
                        return;
                    }
                }
            }
            isStepAgain = StepMatchCount() ? FALSE : TRUE;
        }
        else if ( m_isTillCall ) {
            // Step [Over] Till Call.
            if ( LINE == m_nStepOption || STATEMENT == m_nStepOption ) {
            	
            	if ( StepMatchCall()) { 
            		 if( g_nBankNum && isCallBankSwitch(m_TestAddr.m_uAddr)) {
            			isStepAgain = FALSE;
            		 } else 
                	 if(!IsLibFunction(m_TestAddr.m_uchType,m_TestAddr.m_uAddr)) {
	                    isStepAgain = FALSE;		
	                } else isStepAgain = TRUE;
                }
                else {
                    isStepAgain = TRUE;
                }
            }
            else {      
            	isStepAgain = StepMatchCall() ? FALSE : TRUE;
            }
        }
        else if ( m_isTillRet ) {
            // Step [Over] Till Ret.        
            unsigned int uPC;
            m_nErrorID = AbiGetOneReg(0, &uPC);
            if ( ICE_OK != m_nErrorID ) {
                DisplayErrorMessage();
                return;
            }
            if ( (LINE == m_nStepOption || STATEMENT == m_nStepOption)
            	 && ( g_nBankNum && isRetBankSwitchNext(uPC))) {
            	StepTillSource2();
            	isStepAgain = FALSE;
            } else	    
            ////////////////////////
            isStepAgain = StepMatchRet() ? FALSE : TRUE;
        }
        else if ( m_isAddr ) {
            if ( !isStepAgain ) {
                m_nErrorID = AbiSetReg(0, m_FromAddr.m_uAddr);    // Set PC.
                if ( ICE_OK != m_nErrorID ) {
                    DisplayErrorMessage();
                    return;
                }
                
                m_nErrorID = SetPCBank(m_FromAddr.m_uchType);    // Set PC.
                if ( ICE_OK != m_nErrorID ) {
                    DisplayErrorMessage();
                    return;
                }
            }
            isStepAgain = StepMatchAddr() ? FALSE : TRUE;
        }
        else if ( m_isRegMatch ) {
            isStepAgain = StepMatchReg() ? FALSE : TRUE;
        }
        else if ( m_isMemMatch ) {
            isStepAgain = StepMatchMem() ? FALSE : TRUE;
        }
        else if ( m_isIntoCall ) {
            // Go Into Call (only for Server).                            
            ///////////////////
            if ( StepMatchCall() ) {
            	if( (LINE == m_nStepOption || STATEMENT == m_nStepOption)
            		&& g_nBankNum && isCallBankSwitch(m_TestAddr.m_uAddr)) {
        			//isStepAgain = FALSE;
        			StepTillSourceOne();
        			break;
        		} else 
                if ( (LINE == m_nStepOption || STATEMENT == m_nStepOption) && !IsLibFunction(m_TestAddr.m_uchType,m_TestAddr.m_uAddr) ) {
                    m_isStepOver = FALSE;
                    m_isIntoCall = FALSE;
                }
                else if ( LINE != m_nStepOption && STATEMENT != m_nStepOption ) {
                    m_isStepOver = FALSE;
                    m_isIntoCall = FALSE;
                }
            }
            isStepAgain = TRUE;
        }
        else if ( m_isOverRet ) {
            // Go Over Ret (only for Server).
            // Step [Over] Till Ret.        
            //added 97.1 for bank switch
            unsigned int uPC;
            m_nErrorID = AbiGetOneReg(0, &uPC);
            if ( ICE_OK != m_nErrorID ) {
                DisplayErrorMessage();
                return;
            }
            if ( (LINE == m_nStepOption || STATEMENT == m_nStepOption) && ( g_nBankNum && isRetBankSwitch(uPC)) ) {
            	StepTillSource();
            	isStepAgain = FALSE;
            	m_isOverRet = FALSE;
            }
            else if ( StepMatchRet() ) {
                m_isOverRet = FALSE;
            } 
            isStepAgain = TRUE;
        }
        else {
            isStepAgain = FALSE;
        }

    } while ( isStepAgain );
    
    // Display the step count.
    DisplayStepCount();
    
}   // End of CEmulationStep::StepKernel().


// Step kernel routine.
// AbiStepOne(), AbiStepOver(), AbiStepRange() & AbiStepOverRange().
void CEmulationStep::StepRangeKernel(void)
{
    // Assertion of the input parameters.
    
    // The Step loop.
    BOOL isStepAgain = FALSE;
    unsigned short uStart, uEnd;
    int nBank;
    unsigned int uPC;
    
    //john 96.4
    if(GetXviewAppJohn()->m_nCpuStatus == STATUS_GO ) {
        if ( !m_isServer ) ::ErrShow(ER_GOFLY_ERR_MSG,FALSE);
       		else ::ErrShow(ER_GOFLY_ERR_MSG,TRUE);
        return;                    
    }
    
    do {
        // Get the step option.
        m_nStepOption = ::GetStepOption();

        // High level Step range detection.
        if ( LINE == m_nStepOption || STATEMENT == m_nStepOption ) {

            // Get the source line range.
            GetStepRange(nBank,uStart, uEnd);
            if ( ICE_OK != m_nErrorID ) {
                return;
            }

            // Set the Step range.
            m_FromAddr = CMemoryAddr(uStart, MEM_PROGRAM);
            m_TillAddr = CMemoryAddr(uEnd, MEM_PROGRAM);

            // Call Abi routine.
            if ( !m_isStepOver ) {
                // Step range.
                m_nErrorID = 
                    AbiStepRange((ADDR&)m_FromAddr, (ADDR&)m_TillAddr);
            }
            else {
                // Step Over range.
                m_nErrorID = 
                    AbiStepOverRange((ADDR&)m_FromAddr, (ADDR&)m_TillAddr);
            }
                
            if ( ICE_OK != m_nErrorID ) {
                DisplayErrorMessage();
                return;
            }
        
            // ESC to cancel Step process.
            if ( EscapeAbort() ) {
                return;
            }

            // Get the current PC.
            m_nErrorID = AbiGetOneReg(0, &uPC);
            if ( ICE_OK != m_nErrorID ) {
                DisplayErrorMessage();
                return;
            }

            // Detect PC is already in the range of the lib function.
            // Step range version.
            while ( IsLibFunction(GetPCBank(),(unsigned short)uPC) ) {
                // Get the step range.
                unsigned short uStart, uEnd;
                if ( 0 == GetLibRange(GetPCBank(), (unsigned short)uPC, uStart, uEnd) ) {
                    ASSERT( uStart <= uEnd );
                    if ( uStart > uEnd ) {
                        //AfxMessageBox("Load format error.");
                        m_nStepOption = INSTRUCTION;
                        ::SetStepOption(m_nStepOption);
                        break;
                    }
                }
                else {
                    m_nStepOption = INSTRUCTION;
                    ::SetStepOption(m_nStepOption);
                    break;
                }

                // Set the Step range.
                m_FromAddr = CMemoryAddr(uStart, MEM_PROGRAM);
                m_TillAddr = CMemoryAddr(uEnd, MEM_PROGRAM);

                // Step [Over] range.
                m_nErrorID = 
                    AbiStepRange((ADDR&)m_FromAddr, (ADDR&)m_TillAddr);
                if ( ICE_OK != m_nErrorID ) {
                    DisplayErrorMessage();
                    return;
                }

                // ESC to cancel Step process.
                if ( EscapeAbort() ) {
                    return;
                }

                // Get the current PC.
                m_nErrorID = AbiGetOneReg(0, &uPC);
                if ( ICE_OK != m_nErrorID ) {
                    DisplayErrorMessage();
                    return;
                }
            }
        }
        else {
            // Low level Step instruction.
            if ( !m_isStepOver ) {
                m_nErrorID = AbiStepOne();
            }
            else {
                m_nErrorID = AbiStepOver();
            }
            // Detect ABI error.
            if ( ICE_OK != m_nErrorID ) {
                DisplayErrorMessage();
                return;
            }
            // Mixed or Assemble mode.
            m_uStepCount++;
        }
        
        // ESC to cancel Step process.
        if ( EscapeAbort() ) {
            return;
        }
        
        // Step again?
        if ( m_isStepCount ) {
            // Step [Over] count.
            if ( LINE == m_nStepOption || STATEMENT == m_nStepOption ) {
                if ( uPC < uStart || uPC > uEnd ) {
                    m_uStepCount++;
                }
            }
            isStepAgain = StepMatchCount() ? FALSE : TRUE;
        }
        else {
            isStepAgain = FALSE;
        }

    } while ( isStepAgain );
    
    // Display the step count.
    DisplayStepCount();
    
}   // End of CEmulationStep::StepRangeKernel().


// Get step range based on the source level.
void CEmulationStep::GetStepRange(int& nBankx,unsigned short& uStart,
                                  unsigned short& uEnd)
{
    // Assertion of the input parameters.
    ASSERT( ICE_OK == m_nErrorID );
    ASSERT( LINE == m_nStepOption || STATEMENT == m_nStepOption );
    
    // Get the current PC.
    unsigned int uPC;
    int nBank = GetPCBank();
    nBankx = nBank;
    m_nErrorID = AbiGetOneReg(0, &uPC);
    if ( ICE_OK != m_nErrorID ) {
        DisplayErrorMessage();
        return;
    }

    // Get the step range.
    int nRet;
    if ( LINE == m_nStepOption ) {
        nRet = GetLineRange(nBank,(unsigned short)uPC, uStart, uEnd);
    }
    else {
        nRet = GetStatementRange(nBank,(unsigned short)uPC, uStart, uEnd);
    }
    ASSERT( uStart <= uEnd );
    if ( nRet != 0 || uStart > uEnd ) {
//        ::ErrShow(ER_EMU_LOAD_FORMAT_ERROR,TRUE);
        m_nStepOption = INSTRUCTION;
        ::SetStepOption(m_nStepOption);
    }

    
    // Frank told me to add this function to fix EP_RUNNING.
    m_uBpAddr = uEnd+1;
    m_nBpAddrBank = nBank;                   
    

}   // End of CEmulationStep::Insource().

// Get step range based on the source level.
BOOL CEmulationStep::inSource()
{
    unsigned short uStart;
    unsigned short uEnd;
    
    // Get the current PC.
    unsigned int uPC;
    int nBank = GetPCBank();
    m_nErrorID = AbiGetOneReg(0, &uPC);
    if ( ICE_OK != m_nErrorID ) {
        DisplayErrorMessage();
        return FALSE;
    }

    // Get the step range.
    int nRet;
    if ( LINE == m_nStepOption ) {
        nRet = GetLineRange(nBank,(unsigned short)uPC, uStart, uEnd);
    }
    else {
        nRet = GetStatementRange(nBank,(unsigned short)uPC, uStart, uEnd);
    }        

    if ( nRet != 0 || uStart > uEnd ) {
		return FALSE;
    }                
    
    return TRUE;
    
}   // End of CEmulationStep::GetStepRange().


// Display the step count.
void CEmulationStep::DisplayStepCount(void)
{
    // Assertion of the input parameters.

    // Get the current PC.
    unsigned int uRegValue;
    int nBank = GetPCBank();
    m_nErrorID = AbiGetOneReg(0, &uRegValue);
    if ( ICE_OK != m_nErrorID ) {
        DisplayErrorMessage();
        return;
    }
    
    // Get one byte from PC.
    CMemoryAddr StartAddr((unsigned short) uRegValue, nBank);
    CMemoryAddr EndAddr = StartAddr;
    
    char pchData[4];
    m_nErrorID = AbiGetMemN((ADDR&)StartAddr, (ADDR&)EndAddr, pchData);
    if ( ICE_OK != m_nErrorID ) {
        DisplayErrorMessage();
        return;
    }
    
    // Get the instruction length.
    unsigned char uchInsLen = TRCGetInstLen((unsigned char)pchData[0]);
    ASSERT( uchInsLen >= 1 && uchInsLen <= 3 );
    
    // Get the specific length data from PC.
    EndAddr = StartAddr + (unsigned short)uchInsLen;
    m_nErrorID = AbiGetMemN((ADDR&)StartAddr, (ADDR&)EndAddr, pchData);
    if ( ICE_OK != m_nErrorID ) {
        DisplayErrorMessage();
        return;
    }
    
    // Get the Object code and Instruction.
    char pszTemp[255];
    if ( 0 == TRCGetInst((unsigned short)uRegValue, (unsigned char*)pchData, 
                         uchInsLen, (unsigned char*)pszTemp) ) {
        if ( strlen(pszTemp) > 200 ) {
            ASSERT( FALSE );
            return;
        }                          
        char tmpStr[20];
        ADDRESS addr;            
  		addr.adrSpace = (ADDR_SPACE)nBank;
  		addr.adrAddress = uRegValue;
  
	    ADDR_RETCODE result = AdrDadAddrToHex( addr,tmpStr);
  	 	
        sprintf(m_pszResult, "%s    %s", tmpStr, pszTemp);
        ShowLine(m_pszResult);
    }
    else {
        sprintf(m_pszResult, "Step completed.");
        ShowLine(m_pszResult);
    }

}   // End of CEmulationStep::DisplayStepCount().


// If match the count?
BOOL CEmulationStep::StepMatchCount(void)
{
    // Assertion of the input parameters.
    
    // Attain the count.
    return (m_uStepCount == m_uInputCount) ? TRUE : FALSE;

}   // End of CEmulationStep::StepMatchCount().


// If match the CALL?
BOOL CEmulationStep::StepMatchCall(void)
{
    // Assertion of the input parameters.

    // Get current PC.
    unsigned int uRegValue;
    m_nErrorID = AbiGetOneReg(0, &uRegValue);
    if ( ICE_OK != m_nErrorID ) {
        DisplayErrorMessage();
        return (FALSE);
    }

    // Get the special address memory.
    char pchData[4];
    m_TestAddr.m_uAddr = (unsigned short)uRegValue;
    m_TestAddr.m_uchType = (unsigned char)GetPCBank();
    m_nErrorID = 
        AbiGetMemN((ADDR&)m_TestAddr, (ADDR&)(m_TestAddr+2), pchData);
    if ( ICE_OK != m_nErrorID ) {
        DisplayErrorMessage();
        return (FALSE);
    }
    
    // Check ACALL or LCALL.
    if ( 0x012 == pchData[0] ) {
        // LCALL addr16.
        m_TestAddr.m_uAddr = (unsigned short)
        ( ((((WORD)pchData[1])<<8)&0xFF00) | (((WORD)pchData[2])&0x0FF) );
        return (TRUE);
    }
    else if ( 0x011 == (pchData[0]&0x01F) ) {
        // ACALL addr11.
        WORD w1 = (m_TestAddr.m_uAddr + 2) & 0xF800;
        WORD w2 = ( (((((WORD)pchData[0]&0x0E0)<<3) | 
                    ((WORD)pchData[1])&0x0FF) & 0x07FF) ) & 0x07FF;
        m_TestAddr.m_uAddr = (unsigned short)(w1|w2);
        return (TRUE);
    }
    else {
        return (FALSE);
    }

//    return (0x011==pchData[0]&0x01F || 0x012==pchData[0]) ? TRUE : FALSE;
    
}   // End of CEmulationStep::StepMatchCall().


// If match the RET?
BOOL CEmulationStep::StepMatchRet(void)
{
    // Assertion of the input parameters.

    // Get current PC.
    unsigned int uRegValue;
    m_nErrorID = AbiGetOneReg(0, &uRegValue);
    if ( ICE_OK != m_nErrorID ) {
        DisplayErrorMessage();
        return (FALSE);
    }

    // Get the special address memory.
    char pchData[2];
    m_TestAddr.m_uAddr = (unsigned short)uRegValue;
    m_TestAddr.m_uchType = GetPCBank();
    m_nErrorID = AbiGetMemN((ADDR&)m_TestAddr,(ADDR&)m_TestAddr,pchData);
    if ( ICE_OK != m_nErrorID ) {
        DisplayErrorMessage();
        return (FALSE);
    }
    
    // Check RET or RETI.
    return (0x022==pchData[0] || 0x032==pchData[0]) ? TRUE : FALSE;
    
}   // End of CEmulationStep::StepMatchRet().


// If match the address?
BOOL CEmulationStep::StepMatchAddr(void)
{
    // Assertion of the input parameters.

    // Get current PC.
    unsigned int uRegValue;
    int nBank = GetPCBank();
    m_nErrorID = AbiGetOneReg(0, &uRegValue);
    if ( ICE_OK != m_nErrorID ) {
        DisplayErrorMessage();
        return (FALSE);
    }
    else {
//        return (uRegValue==m_TillAddr.m_uAddr) ? TRUE : FALSE;
		
		// Modified by Chen, 05/30/96
		if ( (uRegValue < m_FromAddr.m_uAddr || uRegValue > m_TillAddr.m_uAddr) &&
			nBank == m_FromAddr.m_uchType ) {
			return TRUE;
		}
		else {
			return FALSE;
		}
    }
    
}   // End of CEmulationStep::StepMatchAddr().


// If match the register?
BOOL CEmulationStep::StepMatchReg(void)
{
    // Assertion of the input parameters.

    // Get the special Register value.
    unsigned int uRegValue;
    m_nErrorID = AbiGetOneReg(m_nRegID, &uRegValue);
    if ( ICE_OK != m_nErrorID ) {
        DisplayErrorMessage();
        return (FALSE);
    }
    else {
        return (uRegValue==m_uRegData) ? TRUE : FALSE;
    }
    
}   // End of CEmulationStep::StepMatchReg().


// If match the memory?
BOOL CEmulationStep::StepMatchMem(void)
{
    // Assertion of the input parameters.

    // Get the special address memory.
    char pchData[2];
    m_nErrorID = AbiGetMemN((ADDR&)m_MatchAddr,(ADDR&)m_MatchAddr,pchData);
    if ( ICE_OK != m_nErrorID ) {
        DisplayErrorMessage();
        return (FALSE);
    }
    else {
        return ((unsigned char)pchData[0]==m_uchMemData) ? TRUE : FALSE;
    }
    
}   // End of CEmulationStep::StepMatchMem().


// Step [count] server.
void CEmulationStep::EmuServerStep(long lCount)
{
    // Assertion of the input parameters.
    ASSERT( lCount >= -4 && lCount <= 0xFFFF );
    // lCount:   1 <= lCount <= 0xFFFF - Count
    //           0 - Continuously
    //          -1 - Till Call
    //          -2 - Till Ret
    //          -3 - Into Call
    //          -4 - Over Ret

    // Set the parameter.
    if ( 0 == lCount ) {
        // Step Forever.
        m_isStepForever = TRUE;
    }
/*    
    else if ( -1 == lCount ) {
        // Step Till Call.
        m_isTillCall = TRUE;
    }
    else if ( -2 == lCount ) {
        // Step Till Ret.
        m_isTillRet = TRUE;
    }
    else if ( -3 == lCount ) {
        // Step Into Call.
        m_isIntoCall = TRUE;
    }
    else if ( -4 == lCount ) {
        // Step Over Ret.
        m_isOverRet = TRUE;
    }
*/
    else if ( lCount >= 1 && lCount <= 0xFFFF ) {
        // Step count.
        m_isStepCount = TRUE;
        m_uInputCount = (unsigned short)lCount;
    }
    else {
        ASSERT( FALSE );
    }
    
    // Call the Step kernel.
    m_isServer = TRUE;
    if ( m_isStepCount ) {
        StepKernel();
    }
    else {
        StepKernel();
    }

}   // End of CEmulationStep::EmuServerStep().


// Step Over [count] server.
void CEmulationStep::EmuServerStepOver(long lCount)
{
    // Assertion of the input parameters.
    ASSERT( lCount >= -4 && lCount <= 0xFFFF );
    // lCount:   1 <= lCount <= 0xFFFF - Count
    //           0 - Continuously
    //          -1 - Till Call
    //          -2 - Till Ret
    //          -3 - Into Call
    //          -4 - Over Ret

    // Set the parameter.
    if ( 0 == lCount ) {
        // Step Over Forever.
        m_isStepForever = TRUE;
    }
    else if ( -1 == lCount ) {
        // Step Over Till Call.
        m_isTillCall = TRUE;
    }
    else if ( -2 == lCount ) {
        // Step Over Till Ret.
        m_isTillRet = TRUE;
    }
    else if ( -3 == lCount ) {
        // Step Over Into Call.
        m_isIntoCall = TRUE;
    }
    else if ( -4 == lCount ) {
        // Step Over Over Ret.
        m_isOverRet = TRUE;
    }
    else if ( lCount >= 1 && lCount <= 0xFFFF ) {
        // Step Over count.
        m_isStepCount = TRUE;
        m_uInputCount = (unsigned short)lCount;
    }
    else {
        ASSERT( FALSE );
    }
    
    // Call the Step kernel.
    m_isStepOver = TRUE;
    m_isServer = TRUE;
    if ( m_isStepCount ) {
        StepKernel();
    }
    else {
        StepKernel();
    }

}   // End of CEmulationStep::EmuServerStepOver().

// Update all the windows.
void CEmulationStep::UpdateAllWindows(void)
{
    // Assertion of the input parameters.

	// Added by Chen, 06/05/96.
	// Return if EP is not halt.
	unsigned char uchStatus;
	if ( FALSE == ::GetCpuStatus(uchStatus) ) {
		return;
	}
	else if ( STATUS_HALT != uchStatus && STATUS_GOMONI != uchStatus ) {
		return;
	}
	

    // Repaint all the windows.
    ::OnEmulation();

    // Update the related window at once.
//    if ( ::isShellOn ) {
//        ::pShellWnd->UpdateWindow();
//    }
    if ( ::isSourceOn ) {
        ::pSourceWnd->UpdateWindow();
    }
    if ( ::isVariableOn ) {
        ::pVariableWnd->UpdateWindow();
    }
    if ( ::isStackOn ) {
        ::pStackWnd->UpdateWindow();
    }
    if ( ::isCpuOn ) {
        ::pCpuWnd->UpdateWindow();
    }
    if ( ::isTraceOn ) {
        ::pTraceWnd->UpdateWindow();
    }
    if ( ::isPeriOn ) {
        ::pPeriWnd->UpdateWindow();
    }
    if ( ::isBMemOn ) {
        ::pBMemWnd->UpdateWindow();
    }
    for ( int i = 0; i <= 2; i++ ) {
        if ( ::isMemOn[i] ) {
            ::pMemWnd[i]->UpdateWindow();
        }
    }
}

//////////////////////////////// End of File ////////////////////////////////
