
/***************************************************************************
**
**    $Header:   D:/EPSLDV1/SRC/LOG/EMUGO.CPP   1.8   20 Jun 1996 09:24:42   ZJRD  $
**
**    $Log:   D:/EPSLDV1/SRC/LOG/EMUGO.CPP  $
** 
**    Rev 1.8   20 Jun 1996 09:24:42   ZJRD
** EasyPack/SLD Version 1.20a
** 
**    Rev 1.6   10 Jun 1996 10:19:20   ZJRD
** EasyPack/SLD Version 1.20
** 
**    Rev 1.5   05 Jun 1996 14:52:14   ZJRD
** No change.
** 
**    Rev 1.4   29 May 1996 09:28:20   ZJRD
** No change.
** 
**    Rev 1.3   16 May 1996 09:08:42   ZJRD
** No change.
** 
**    Rev 1.2   10 May 1996 09:08:12   ZJRD
** No change.
** 
**    Rev 1.1   02 May 1996 10:25:40   ZJRD
** EasyPack/SLD Version 1.92
** 
**    Rev 1.31   18 Apr 1996 12:57:28   Shirley
** EasyPack/SLD Version 1.91
** 
**    Rev 1.30   12 Apr 1996 10:42:56   Shirley
** EasyPack/SLD Version 1.90
** 
**    Rev 1.28   15 Feb 1996 08:55:00   Shirley
** No change.
** 
**    Rev 1.27   12 Feb 1996 14:03:14   Shirley
** No change.
** 
**    Rev 1.26   06 Feb 1996 15:29:44   Shirley
** No change.
** 
**    Rev 1.25   06 Feb 1996 13:44:06   Shirley
** No change.
** 
**    Rev 1.24   01 Feb 1996 10:17:02   Shirley
** No change.
** 
**    Rev 1.23   26 Jan 1996 09:19:38   Shirley
** No change.
** 
**    Rev 1.22   25 Jan 1996 13:19:32   Shirley
** No change.
** 
**    Rev 1.21   24 Jan 1996 10:32:40   Shirley
** No change.
** 
**    Rev 1.20   23 Jan 1996 11:24:24   Shirley
** No change.
** 
**    Rev 1.19   18 Jan 1996 10:11:08   Shirley
** No change.
** 
**    Rev 1.18   15 Jan 1996 16:12:44   Shirley
** No change.
** 
**    Rev 1.17   04 Jan 1996 11:10:48   Shirley
** No change.
** 
**    Rev 1.16   30 Nov 1995 09:14:08   Shirley
** No change.
** 
**    Rev 1.15   28 Nov 1995 15:33:02   Shirley
** No change.
** 
**    Rev 1.14   21 Nov 1995 11:23:32   Shirley
** EasyPack/SLD Version 0.31
** 
**    Rev 1.13   13 Nov 1995 09:25:54   Shirley
** No change.
** 
**    Rev 1.12   12 Nov 1995 11:28:48   Shirley
** No change.
** 
**    Rev 1.11   08 Nov 1995 16:29:36   Shirley
** No change.
** 
**    Rev 1.10   08 Nov 1995 12:40:06   Shirley
** No change.
** 
**    Rev 1.9   02 Nov 1995 10:08:30   Shirley
** No change.
** 
**    Rev 1.8   27 Oct 1995 16:45:58   Shirley
** No change.
** 
**    Rev 1.7   27 Oct 1995 13:48:04   Shirley
** No change.
** 
**    Rev 1.6   25 Oct 1995 14:29:22   Shirley
** EasyPack/SLD Version 0.1f
** 
**    Rev 1.5   18 Oct 1995 14:50:52   Shirley
** No change.
** 
**    Rev 1.4   13 Oct 1995 13:22:36   Shirley
** No change.
** 
**    Rev 1.3   29 Sep 1995 09:53:10   Shirley
** EasyPack/SLD Version 0.1c
** 
**    Rev 1.2   20 Sep 1995 10:54:08   Shirley
** No change.
** 
**    Rev 1.1   15 Sep 1995 09:45:34   Shirley
** No change.
** 
**    Rev 1.0   07 Sep 1995 09:55:38   Shirley
** Initial revision.
**
****************************************************************************/

/////////////////////////////////////////////////////////////////////////////
//
//  File name: EMUGO.CPP
//
//  Description: The implementation file for the class: CEmulationGo.
//
//  Author: John Zhou
//
//  Date: 05/06/95
//
//  Modification:
//      1. 05/06/95, Initial version of the class: CEmulationGo.
//
/////////////////////////////////////////////////////////////////////////////


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

#include "uicom.h"

//added by john
#include "abiextfn.h"
#include "cpust.h"
#include "errcodec.h"
#include "mainfrm.h"

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

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


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


/////////////////////////////////////////////////////////////////////////////
// Global variables.


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


/////////////////////////////////////////////////////////////////////////////
// External variables.


/////////////////////////////////////////////////////////////////////////////
// Global function prototypes.
extern void ErrShow(U32 errorCode,BOOL bUI); //JOHN 96.3
void TraceWnd(unsigned char trace);           //
void GoCmd(int nArgc, char* pszArgv[]);
void EmuServerGo(int nMode, unsigned short uAddr);
int TestKey(WORD wKey);

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


/////////////////////////////////////////////////////////////////////////////
// External function prototypes.
#ifndef _SERVER_NO_ABI
    extern STATUS AbiGo(FLAG runFlag, ADDR fromAddr, ADDR tillAddr);
    extern STATUS AbiGetBp(ADDR addr1, ADDR addr2, ADDR* bpAddr);
    extern STATUS AbiSetBp(ADDR addr);
    extern STATUS AbiClrBp(ADDR addr);
    extern STATUS AbiGetCpuStatus(UINT *uCpuStatus);
    extern STATUS AbiGetOneReg(int iRegId, UINT* uRegValue); 
    extern STATUS AbiAbort();
#endif  // _SERVER_NO_ABI
int GetSourceAddr(ADDR& addr);



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

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

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   GoCmd().
//
//  Description: The main control routine of Go command.
//
//  Input:  nArgc - Number of input parameters.
//          pszArgv - Input parameters.
//
//  Output: None.
//
//  Return: None.
//
/////////////////////////////////////////////////////////////////////////////
void GoCmd(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 Go command.
    CEmulationGo* pEmulationGo = new CEmulationGo;
    if ( !pEmulationGo ) {
    	::ErrShow(ER_EMU_INSUFFICIENT_MEMORY,TRUE);
        ASSERT( FALSE );
        return;
    }
    else {  
        pEmulationGo->GoAction(nArgc, pszArgv);
        delete pEmulationGo;
    }
    
//    CEmulationGo objGo;
//    objGo.GoAction(nArgc, pszArgv);

}   // End of GoCmd().


// Emulation Go server.
void EmuServerGo(int nMode, unsigned short uAddr)
{
    // Assertion of the input parameters.
    // nMode:   1 - Go
    //          2 - Go From Addr
    //          3 - Go Till Addr
    //added by john 96.3
    //          4 - go fly
    //          5 - go fly from Addr
    //          6 - go fly till addr
    //ASSERT( 1 == nMode || 2 == nMode || 3 == nMode || 
    //        4 == nMode || 5 == nMode || 6 == nMode );
    
    // Go server for the Source window.
    CEmulationGo* pEmulationGo = new CEmulationGo;
    if ( !pEmulationGo ) {                         
    	::ErrShow(ER_EMU_INSUFFICIENT_MEMORY,TRUE);
        ASSERT( FALSE );
        return;
    }
    else {
        pEmulationGo->EmuServerGo(nMode, uAddr);
        delete pEmulationGo;
    }

}   // End of EmuServerGo().


/////////////////////////////////////////////////////////////////////////////
// Implementation codes of class: CEmulationGo.

// Construction.
CEmulationGo::CEmulationGo()
{
    // Assertion of the input parameters.
    

    m_nMonitorTimer = 0;
    m_bStartTimer = FALSE;
    m_uchFlyFlag = 0;

}   // End of CEmulationGo::CEmulationGo().


// Destruction.
CEmulationGo::~CEmulationGo()
{
    // Assertion of the input parameters.
    

}   // End of CEmulationGo::~CEmulationGo().


// Emulation Go command.
void CEmulationGo::GoAction(int nArgc, char* pszArgv[])
{
    // Assertion of the input parameters.
    //ASSERT( nArgc >= 1 && nArgc <= 5 );
    int i =0;
    for ( i = 0; i < nArgc; i++ ) {
        ASSERT( pszArgv[i] );
    }
    
    SetFlyFlag(0);
    //added by john 96.3 to support go fly anlysis
    char * ppTmpContain[20] ;
    ASSERT(nArgc<20);
    int j = 0;
    for (i = 0; i < nArgc; i++ ) 
        if ( 0 != stricmp(pszArgv[i], "FLY" )) {
            ppTmpContain[j++] = pszArgv[i];
        } else SetFlyFlag(1);   
    nArgc = j;    
    
    // Set the parameters.
    switch ( nArgc ) {
        case 1:
            // Go
            SetRunFlag(0);
            SetAddrVar(MEM_UNDEFINE, 0, m_FromAddr);
            SetAddrVar(MEM_UNDEFINE, 0, m_TillAddr);
            break;
        case 2:
            SetRunFlag(1);
            SetAddrVar(MEM_UNDEFINE, 0, m_FromAddr);
            SetAddrVar(MEM_UNDEFINE, 0, m_TillAddr);
            break;
        case 3:
            // Go [From adr1] | [Till adr2] | Monitor count
            SetRunFlag(0);
            if ( 0 == stricmp(ppTmpContain[1], "FROM") ) {
                SetAddrVar(ppTmpContain[2], m_FromAddr);
                SetAddrVar(MEM_UNDEFINE, 0, m_TillAddr);
            }
            else if ( 0 == stricmp(ppTmpContain[1], "TILL") ) {
                SetAddrVar(MEM_UNDEFINE, 0, m_FromAddr);
                SetAddrVar(ppTmpContain[2], m_TillAddr);
            }
            else {
                SetMonitorTimer(ppTmpContain[2]);
                SetAddrVar(MEM_UNDEFINE, 0, m_FromAddr);
                SetAddrVar(MEM_UNDEFINE, 0, m_TillAddr);
            }
            break;
        case 4:
            // Go Run [From adr1]
            SetRunFlag(1);
            SetAddrVar(ppTmpContain[3], m_FromAddr);
            SetAddrVar(MEM_UNDEFINE, 0, m_TillAddr);
            break;
        case 5:
            // Go From adr1 Till adr2
            SetRunFlag(0);
            SetAddrVar(ppTmpContain[2], m_FromAddr);
            SetAddrVar(ppTmpContain[4], m_TillAddr);
            break;
        default:
            ASSERT( FALSE );
            break;
    }
    
    // Call the Go kernel.
    GoKernel();                                        
    
    //delete ppTmpContain;

}   // End of CEmulationGo::GoAction().


// Set the Run flag.
void CEmulationGo::SetRunFlag(unsigned char uchRunFlag)
{
    // Assertion of the input parameters.
    ASSERT( 0 == uchRunFlag || 1 == uchRunFlag );
    
    // Set the Run flag.
    m_uchRunFlag = uchRunFlag;

}   // End of CEmulationGo::SetRunFlag().

// Set the Run flag.
void CEmulationGo::SetFlyFlag(unsigned char uchFlyFlag)
{
    // Assertion of the input parameters.
    ASSERT( 0 == uchFlyFlag || 1 == uchFlyFlag );
    
    // Set the Run flag.
    m_uchFlyFlag = uchFlyFlag;

}   // End of CEmulationGo::SetRunFlag().


// Go kernel routine.
void CEmulationGo::GoKernel(void)
{
    // Assertion of the input parameters.
    
    // Test parameters.
    //DumpVar(m_uchRunFlag);
    //DumpVar((unsigned long)m_FromAddr.m_uAddr);
    //DumpVar((unsigned long)m_TillAddr.m_uAddr);
    //added by 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;                    
    }
    if(GetXviewAppJohn()->m_nCpuStatus == STATUS_GORUN) {
    	if(0 == m_uchRunFlag && m_nMonitorTimer <= 0 &&
    	   MEM_UNDEFINE == m_FromAddr.m_uchType && MEM_UNDEFINE == m_TillAddr.m_uchType) {
    		CpuHalt();             
    		GoForGofly();
    		if ( !m_isServer ) ::ErrShow(ER_EMU_PROGRAM_IS_RUN,FALSE);
            return;
    	} else {
        	if ( !m_isServer ) ::ErrShow(ER_GOFLY_ERR_MSG,FALSE);
        		else ::ErrShow(ER_GOFLY_ERR_MSG,TRUE);
        	return;                    
        }
    }
    ASSERT(!(1 == m_uchRunFlag && 1 == m_uchFlyFlag));
    // Call the ABI function. 
    TraceWnd(1); //TRACE ON 
    m_nErrorID = AbiGo(m_uchRunFlag, (ADDR&)m_FromAddr, (ADDR&)m_TillAddr);
    if ( ICE_OK != m_nErrorID ) {
        DisplayErrorMessage();
        return;
    }
    else {       
        if ( !m_isServer ) ::ErrShow(ER_EMU_PROGRAM_IS_RUN,FALSE);
    }
    
    //added by john 96.3
    if (m_nMonitorTimer <= 0) {
        (GetXviewAppJohn()->m_GoArg).addrType = m_TillAddr.m_uchType;
        (GetXviewAppJohn()->m_GoArg).addr = m_TillAddr.m_uAddr;
        // check run status john 96.3
        if ( 1 == m_uchRunFlag ) {
            GetXviewAppJohn()->m_nCpuStatus = STATUS_GORUN;
            ShowLine("Program is free running.");
            return;
        } else {
            if ( 1 == m_uchFlyFlag) {
                GetXviewAppJohn()->m_nCpuStatus = STATUS_GOFLY;
            } else GetXviewAppJohn()->m_nCpuStatus = STATUS_GO;        
        }    
    return;    
    }    
                
    
    // Test the EP status.
    GetXviewAppJohn()->DoWaitCursor(1);           
    GetXviewAppJohn()->m_nCpuStatus = STATUS_GOMONI;
    ((CMainFrame*)(GetXviewAppJohn()->m_pMainWnd))->m_wndStatusBar.UpdateStatusBar(2, "Running");
    ((CMainFrame*)(GetXviewAppJohn()->m_pMainWnd))->m_wndStatusBar.UpdateWindow();
    do {
        // ESC to cancel Go command.
        if ( EscapeAbort() ) {
            m_nErrorID = AbiAbort();
            if ( 0 != m_nErrorID ) {
                DisplayErrorMessage();
            }
            else {
				if ( 0 == ::GetSourceAddr((ADDR&)(m_TillAddr)) ) {
				    // Call the ABI function.
				    m_uchRunFlag = 0;
				    m_FromAddr.m_uchType = MEM_UNDEFINE;
    				m_nErrorID = AbiGo(m_uchRunFlag,(ADDR&)m_FromAddr,(ADDR&)m_TillAddr);
				    if ( ICE_OK != m_nErrorID ) {
				        DisplayErrorMessage();
				    }
				    else {
					    // Get CPU status.
					    UINT uCpuStatus;
					    int nCount = 0;
					    do {
					    	AbiGetCpuStatus(&uCpuStatus);
					    	nCount++;
					    } while (  0x40==(uCpuStatus & 0x070) && nCount < 10 );
				    }
                }
            }
            break;
        }
        
        // Start monitor timer.
        if ( m_nMonitorTimer > 0 && !m_bStartTimer ) {
            m_bStartTimer = TRUE;
            m_nTimerCount = 0;
        }
        
        // On monitor timer.
        if ( m_bStartTimer ) {
        	for(int i=0;i<m_nMonitorTimer;i++) {

        		DelayOneSecond();

		        // ESC to cancel Go command.
		        if ( EscapeAbort() ) {
		            m_nErrorID = AbiAbort();
		            if ( 0 != m_nErrorID ) {
		                DisplayErrorMessage();
		            }
	                goto _Exit;
		        }
        	}
        	
            m_nErrorID = AbiAbort();
            if ( 0 != m_nErrorID ) {
                DisplayErrorMessage();
                break;
            }
                
            UpdateAllWindows();
            m_bStartTimer = FALSE;
            m_nErrorID = AbiGo(m_uchRunFlag, 
                               (ADDR&)m_FromAddr, (ADDR&)m_TillAddr);
            if ( 0 != m_nErrorID ) {
                DisplayErrorMessage();
                break;
            }
        }

        // Detect if EP is stopped.
        /*
        if ( DetectEPStop() ) {
            if ( !MatchPatch() ) {
                ShowLine("Program is stopped.");
                break;
            }
            else {
                m_nErrorID =
                AbiGo(m_uchRunFlag, (ADDR&)m_FromAddr, (ADDR&)m_TillAddr);
                if ( ICE_OK != m_nErrorID ) {
                    DisplayErrorMessage();
                    break;
                }
            }
        } */
    } while ( TRUE );
    
_Exit:
    GetXviewAppJohn()->DoWaitCursor(-1);
        
    GetXviewAppJohn()->m_nCpuStatus = STATUS_HALT;
    ((CMainFrame*)(GetXviewAppJohn()->m_pMainWnd))->m_wndStatusBar.UpdateStatusBar(2, "Halt");
    ((CMainFrame*)(GetXviewAppJohn()->m_pMainWnd))->m_wndStatusBar.UpdateWindow();
}   // End of CEmulationGo::GoKernel().

void CEmulationGo::SetMonitorTimer(char* pszTimer)
{
    StrToVar(pszTimer);
    m_nMonitorTimer = (int)m_ulVar;
}

 
// Detect if EP is stopped.
BOOL CEmulationGo::DetectEPStop(void)
{
    // Assertion of the input parameters.

/*    
    // Set EV3 to detect.
    BUS_EVENT BusEvent;
    memset(&BusEvent, 0, sizeof(BUS_EVENT));
    BusEvent.qlfyType[0] = 3;
    BusEvent.qlfyType[9] = 1;
    BusEvent.extrn = 0;
    
    m_nErrorID = AbiSetEvent(BusEvent);
    if ( ICE_OK == m_nErrorID ) {
        return (TRUE);
    }
    else if ( ICE_EP_RUNNING == m_nErrorID ) {
        return (FALSE);
    }
    else {
        DisplayErrorMessage();
        return (TRUE);
    }
*/
    
    // Delay one second.
//    DelayOneSecond();
                            
    // Get CPU status.
    UINT uCpuStatus;
    m_nErrorID = AbiGetCpuStatus(&uCpuStatus);
    if ( ICE_OK != m_nErrorID ) {
        DisplayErrorMessage();
        return (TRUE);
    }

    // Detect if EP is running.
    return ( 0x40 == (uCpuStatus & 0x070) ) ? FALSE : TRUE;

}   // End of CEmulationGo::DetectEPStop().



// Go server.
void CEmulationGo::EmuServerGo(int nMode, unsigned short uAddr)
{
    // Assertion of the input parameters.
    //ASSERT( 1 == nMode || 2 == nMode || 3 == nMode );
    // nMode:   1 - Go
    //          2 - Go From Addr
    //          3 - Go Till Addr
    //added by john 96.3
    //          4 - go fly 
    //			5 - go fly from addr
    //			6 - go fly till addr
    //          7 - go run
    //          8 - go monitor
    // Dispatch the different mode.
    switch ( nMode ) {
        case 1:
            // Go
            SetRunFlag(0);
            SetAddrVar(MEM_UNDEFINE, 0, m_FromAddr);
            SetAddrVar(MEM_UNDEFINE, 0, m_TillAddr);
            break;
        case 2:
            // Go From Addr
            SetRunFlag(0);
            m_FromAddr = CMemoryAddr(uAddr, MEM_PROGRAM);
            SetAddrVar(MEM_UNDEFINE, 0, m_TillAddr);
            break;
        case 3:
            // Go Till Addr
            SetRunFlag(0);
            SetAddrVar(MEM_UNDEFINE, 0, m_FromAddr);
            m_TillAddr = CMemoryAddr(uAddr, MEM_PROGRAM);
            break;                                       
        case 4:
            // Go fly
            SetFlyFlag(1);
            SetRunFlag(0);
            SetAddrVar(MEM_UNDEFINE, 0, m_FromAddr);
            SetAddrVar(MEM_UNDEFINE, 0, m_TillAddr);
            break;
        case 5:
            // Go fly From Addr
            SetFlyFlag(1);
            SetRunFlag(0);
            m_FromAddr = CMemoryAddr(uAddr, MEM_PROGRAM);
            SetAddrVar(MEM_UNDEFINE, 0, m_TillAddr);
            break;
        case 6:
            // Go fly Till Addr
            SetFlyFlag(1);
            SetRunFlag(0);
            SetAddrVar(MEM_UNDEFINE, 0, m_FromAddr);
            m_TillAddr = CMemoryAddr(uAddr, MEM_PROGRAM);
            break;    
        case 7:
            // Go run
            SetRunFlag(1);
            SetAddrVar(MEM_UNDEFINE, 0, m_FromAddr);
            SetAddrVar(MEM_UNDEFINE, 0, m_TillAddr);
            break;        
        case 8:
            // Go monitor time
            m_nMonitorTimer = (int)uAddr;
            SetAddrVar(MEM_UNDEFINE, 0, m_FromAddr);
            SetAddrVar(MEM_UNDEFINE, 0, m_TillAddr);
            break;
            
        default:
            ASSERT( FALSE );
            return;
            break;
    }
    
    // Call the Go kernel.
    m_isServer = TRUE;
    GoKernel();

}   // End of CEmulationGo::EmuServerGo().

// Update all the windows.
void CEmulationGo::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();
        }
    }
} 
//ADDED BY JOHN 96.3 SUPPORT THE GO FLY FUNCTION
//NOW IT IS ONLY USED IN CHANGING GO STATUS FROM GORUN TO GO
BOOL CEmulationGo::GoForGofly()
{                   
    if(GetXviewAppJohn()->m_nCpuStatus != STATUS_HALT )  return FALSE;
    SetRunFlag(0);
    SetAddrVar(MEM_UNDEFINE, 0, m_FromAddr);
    SetAddrVar(MEM_PROGRAM,(unsigned long)((GetXviewAppJohn()->m_GoArg).addr), 
               m_TillAddr);
    m_nErrorID = AbiGo(m_uchRunFlag, (ADDR&)m_FromAddr, (ADDR&)m_TillAddr);
    if ( ICE_OK != m_nErrorID ) {
        DisplayErrorMessage();
        return FALSE;
    }
    else {
        GetXviewAppJohn()->m_nCpuStatus = STATUS_GO;
        return TRUE;
    }
 
 return TRUE; 
 
 }

//ADDED BY JOHN 96.3
/**************************************************************************
**
** Name : GetCpuStatus()
**
** Function  is called by others to get the current cpu status in go status
**
**    Input  : 
**
**    Output : uchStatus = the current cpu status
**             STATUS_HALT == 0
**             STATUS_GO   == 1
**             STATUS_GORUN == 2
**             STATUS_GOFLY == 3   
**    returN : TRUE ==> GET OK
**             FALSE ==> GET FAIL
** Notes:
**
**************************************************************************/
BOOL GetCpuStatus(unsigned char & uchStatus)
{          
    uchStatus = GetXviewAppJohn()->m_nCpuStatus;
    return TRUE;
 }

//ADDED BY JOHN 96.3
/**************************************************************************
**
** Name : WaitCmd()
**
** Function  is called by SHELL WINDOW TO do the wait cmd
**
**    Input  : 
**
**    Output : 
**    returN : 
** Notes:
**
**************************************************************************/
void WaitCmd()
{       
    unsigned char uchStatus;      
    UINT iAbiCpuStatus;                                 
    if(STATUS_HALT == GetXviewAppJohn()->m_nCpuStatus) return;
    GetXviewAppJohn()->m_bCanTimer = FALSE;
    while (1) {
    	AbiGetCpuStatus(&iAbiCpuStatus);
    	if (  0x40==(iAbiCpuStatus & 0x070) ) 
            GetXviewAppJohn()->m_nCpuStatus = GetXviewAppJohn()->m_nCpuStatus; 
        else GetXviewAppJohn()->m_nCpuStatus = STATUS_HALT;
        if ( 0x04 == (iAbiCpuStatus & 0x04)) 
            GetXviewAppJohn()->m_bTraceOn = TRUE;
        else GetXviewAppJohn()->m_bTraceOn = FALSE;   
        uchStatus = GetXviewAppJohn()->m_nCpuStatus;
    	if(STATUS_HALT == uchStatus) break;
    	if(TestKey(VK_ESCAPE)) break;
    }	                            
    GetXviewAppJohn()->m_bCanTimer = TRUE;
 }


/**************************************************************************
**
** Name : ContinueGo()
**
** Function  support go fly function
**
**    Input  : 
**
**    return : TRUE ==>  OK
**             FALSE ==> FAIL
** Notes:
**
**************************************************************************/
BOOL ContinueGo()       
{                                           
    CEmulationGo* pEmulationGo = new CEmulationGo;
    if ( !pEmulationGo ) {
        ::ErrShow(ER_EMU_INSUFFICIENT_MEMORY,TRUE);
        ASSERT( FALSE );
        return FALSE;
    }
    else {  
        BOOL bResult = pEmulationGo->GoForGofly();
        delete pEmulationGo;
        return bResult;
    }
 
    return TRUE;
 }
//////////////////////////////// End of File ////////////////////////////////
