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

/////////////////////////////////////////////////////////////////////////////
//
//  File name: MEMFILL.CPP
//
//  Description: The implementation file for the class: CMemoryFill.
//
//  Author: Chen Jun
//
//  Date: 04/26/95
//
//  Modification:
//      1. 04/26/95, Initial version of the class: CMemoryFill.
//
/////////////////////////////////////////////////////////////////////////////


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

#include "memfill.h"
#include "hosterrs.h"
extern RETCODE EXPORT ErrGetErrorText(U32 errorCode, LPSTR lpszError ...);
extern RETCODE EXPORT ErrGetErrorText(U32 errorCode, CString& strError ...);


/////////////////////////////////////////////////////////////////////////////
// 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.
void FillCmd(int nArgc, char* pszArgv[]);
int MemServerFill(long lAddr, BYTE bValue, int nType);
void MemServerFill(const unsigned short uStart, const unsigned short uEnd,
                   const unsigned char uchType, char* szPattern);


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


/////////////////////////////////////////////////////////////////////////////
// External function prototypes.
#ifndef _SERVER_NO_ABI
    extern STATUS AbiFill(ADDR addr1, ADDR addr2, char* pchBuff, 
                          UINT uPatternLen);
    extern ADDR AbiGetErrorAddr();
#endif  // _SERVER_NO_ABI

void SrcUpdate(void);
extern BOOL GetCpuStatus(unsigned char &);
extern void ShowLine(char *);




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

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

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   FillCmd().
//
//  Description: The main control routine of Fill command.
//
//  Input:  nArgc - Number of input parameters.
//          pszArgv - Input parameters.
//
//  Output: None.
//
//  Return: None.
//
/////////////////////////////////////////////////////////////////////////////
void FillCmd(int nArgc, char* pszArgv[])
{
    // Assertion of the input parameters.
    ASSERT( 4 == nArgc || 5 == nArgc );
    for ( int i = 0; i < nArgc; i++ ) {
        ASSERT( pszArgv[i] );
    }
    
    // Fill to EMM.
    char error[128];
    CMemoryFill* pMemoryFill = new CMemoryFill;
    if ( !pMemoryFill ) {
        AfxMessageBox("Insufficient Memory !");
        ASSERT( FALSE );
        return;
    }
    else {
       unsigned char result;         
       if ( ::GetCpuStatus(result) ) {
          if ( 1/*STATUS_GO*/ == result ) {
            //::ShowLine ("EP running. Stop EP first");
            ::ErrGetErrorText(ER_GOFLY_ERR_MSG, error);
            ::ShowLine (error);
          }    
          else {
            pMemoryFill->FillAction(nArgc, pszArgv);
          }           
       }   
       delete pMemoryFill;
    }

//    CMemoryFill objFill;
//    objFill.FillMemory(nArgc, pszArgv);

}   // End of FillCmd().


/////////////////////////////////////////////////////////////////////////////
//
//  Name:   MemServerFill().
//
//  Description: The main control routine of Fill Server.
//
//  Input:  lAddr - Start address.
//          bValue - Value which will be filled.    
//          nType - Memory space type.
//
//  Output: None.
//
//  Return: Error ID.
//
/////////////////////////////////////////////////////////////////////////////
int MemServerFill(long lAddr, BYTE bValue, int nType)
{
    // Assertion of the input parameters.
    ASSERT( nType >= 1 && nType <= 5 );
    
    // Fill to EMM.
    CMemoryFill* pMemoryFill = new CMemoryFill;
    if ( !pMemoryFill ) {
        AfxMessageBox("Insufficient Memory !");
        ASSERT( FALSE );
        return (0);
    }
    else {
        int nRetError = 
            pMemoryFill->MemServerFill((WORD) lAddr, bValue, nType);
        delete pMemoryFill;
        return (nRetError);
    }

//    CMemoryFill objFill;
//    int nRetError = objFill.MemServerFill((WORD) lAddr, bValue, nType);
//    return (nRetError);

}   // End of MemServerFill().


// Fill server for Fill dialog.
void MemServerFill(const unsigned short uStart, const unsigned short uEnd,
                   const unsigned char uchType, char* pszPattern)
{
    // Assertion of the input parameters.
    ASSERT( uchType >= 1 && uchType <= 5 );

    // Fill to EMM.
    CMemoryFill* pMemoryFill = new CMemoryFill;
    if ( !pMemoryFill ) {
        AfxMessageBox("Insufficient Memory !");
        ASSERT( FALSE );
    }
    else {
        pMemoryFill->MemServerFill(uStart, uEnd, uchType, pszPattern);
        delete pMemoryFill;
    }
}


/////////////////////////////////////////////////////////////////////////////
// Implementation codes of class: CMemoryFill.

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   CMemoryFill::CMemoryFill().
//
//  Description: The construction of the class: CMemoryFill.
//
//  Input:  None.
//
//  Output: None.
//
//  Return: None.
//
/////////////////////////////////////////////////////////////////////////////
CMemoryFill::CMemoryFill()
{

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


/////////////////////////////////////////////////////////////////////////////
//
//  Name:   CMemoryFill::~CMemoryFill().
//
//  Description: The destruction of the class: CMemoryFill.
//
//  Input:  None.
//
//  Output: None.
//
//  Return: None.
//
/////////////////////////////////////////////////////////////////////////////
CMemoryFill::~CMemoryFill()
{

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



/////////////////////////////////////////////////////////////////////////////
//
//  Name:   CMemoryFill::FillAction().
//
//  Description: Fill to EMM.
//
//  Input:  None.
//
//  Output: None.
//
//  Return: None.
//
/////////////////////////////////////////////////////////////////////////////
void CMemoryFill::FillAction(int nArgc, char* pszArgv[])
{
    // Assertion of the input parameters.
    ASSERT( 4 == nArgc || 5 == nArgc );
    for ( int i = 0; i < nArgc; i++ ) {
        ASSERT( pszArgv[i] );
    }
    
    // Set Start address & End address.
    if ( 4 == nArgc ) {
        // Fill adr1 adr2 "string"|data.
        SetAddrVar(pszArgv[1], m_StartAddr);
        SetAddrVar(pszArgv[2], m_EndAddr);
        SetPattern(pszArgv[3]);
    }
    else if ( 5 == nArgc ) {
        // Fill adr1 Length length "string"|data.
        SetAddrVar(pszArgv[1], m_StartAddr);
        SetAddrVar(pszArgv[1], pszArgv[3], m_EndAddr);
        SetPattern(pszArgv[4]);
    }
    else {
        ASSERT( FALSE );
        return;
    }
    
    // Set the default memory space.
    if ( ':' != pszArgv[1][1] ) {
        m_StartAddr.m_uchType = MEM_EXTERNAL;
    }
    m_EndAddr.m_uchType = m_StartAddr.m_uchType;
    
    // Memory Fill kernel routine.
    MemoryFillKernel();
        
}   // End of CMemoryFill::FillAction().


void CMemoryFill::SetPattern(char* pszPattern)
{
    // Assertion of the input parameters.
    ASSERT( pszPattern );
    
    // Set the pattern buffer.
    if ( '\"' == *pszPattern ) {
        // Set "string".
        m_uPatternLen = strlen(pszPattern) - 2;
        pszPattern[m_uPatternLen+1] = 0;
        strcpy(m_pchFill, pszPattern+1);
    }
    else {
        // Set Data: "12 34 ".
        m_uPatternLen = 0;
        while ( *pszPattern ) {
            char pszData[3];
            memset(pszData, 0, sizeof(pszData));
            for ( int i = 0; i <= 2; i++ ) {
                if ( ' ' != *pszPattern ) {
                    pszData[i] = *pszPattern++;
                }
                else {
                    pszPattern++;
                    break;
                }
            }
            StrToVar(pszData);
            m_pchFill[m_uPatternLen++] = (BYTE) m_ulVar;
        }
    }

}   // End of CMemoryFill::SetPattern().


void CMemoryFill::MemoryFillKernel(void)
{
    // Assertion of the input parameters.
    
    // Call Abi routine.
    m_nErrorID = AbiFill((ADDR&) m_StartAddr, (ADDR&) m_EndAddr,
                         m_pchFill, m_uPatternLen);

    // Update Source window.
    if ( MEM_PROGRAM == m_StartAddr.m_uchType ) {
        ::SrcUpdate();
    }

    // Get the error address.
    if ( ICE_FAIL_MEM_WRITE == m_nErrorID ) {
        m_FailAddr = (CMemoryAddr&) AbiGetErrorAddr();
        char chType;
        switch ( m_FailAddr.m_uchType ) {
            case MEM_UNDEFINE:
                switch ( m_StartAddr.m_uchType ) {
                    case MEM_PROGRAM:
                        chType = 'P';
                        break;
                    case MEM_EXTERNAL:
                        chType = 'X';
                        break;
                    case MEM_INTERNAL:
                        chType = 'I';
                        break;
                    case MEM_SFR:
                        chType = 'R';
                        break;
                    case MEM_BIT:
                        chType = 'B';
                        break;
                    default:
                        ASSERT( FALSE );
                        break;
                }
                break;
            case MEM_PROGRAM:
                chType = 'P';
                break;
            case MEM_EXTERNAL:
                chType = 'X';
                break;
            case MEM_INTERNAL:
                chType = 'I';
                break;
            case MEM_SFR:
                chType = 'R';
                break;
            case MEM_BIT:
                chType = 'B';
                break;
            default:
                ASSERT( FALSE );
                break;
        }
        wsprintf(m_pszResult, "Memory write failure at: %c:%04X.",
                    chType, m_FailAddr.m_uAddr);
        if ( !m_isServer ) {
            ShowLine(m_pszResult);
        }
        else {
            AfxMessageBox(m_pszResult);
        }
    }
    else if ( 0 != m_nErrorID ) {
        DisplayErrorMessage();
    }
        
}   // End of CMemoryFill::MemoryDumpKernel().



/////////////////////////////////////////////////////////////////////////////
//
//  Name:   CMemoryFill::MemServerFill().
//
//  Description: Fill EMM for UI.
//
//  Input:  wAddr - Start address.
//          bValue - Value which will be filled.    
//          nType - Memory space type.
//
//  Output: None.
//
//  Return: Error ID.
//
/////////////////////////////////////////////////////////////////////////////
int CMemoryFill::MemServerFill(WORD wAddr, BYTE bValue, int nType)
{
    // Assertion of the input parameters.
    ASSERT( nType >= 1 && nType <= 5 );

    // Set the parameters.
    CMemoryAddr StartAddr(wAddr, (unsigned char) nType);
    CMemoryAddr EndAddr = StartAddr;
    
    char pszBuffer[1];
    pszBuffer[0] = (char) bValue;
        
    // Call ABI routine.
    m_nErrorID = AbiFill((ADDR&)StartAddr, (ADDR&)EndAddr, pszBuffer, 1);
    m_isServer = TRUE;

    // Update Source window.
    if ( MEM_PROGRAM == nType ) {
        ::SrcUpdate();
    }

    if ( ICE_OK != m_nErrorID ) {
        DisplayErrorMessage();
    }

    return (m_nErrorID);

}   // End of CMemoryFill::MemServerFill().


// Fill server for Fill dialog.
void CMemoryFill::MemServerFill(const unsigned short uStart, 
    const unsigned short uEnd, const unsigned char uchType, char* pszPattern)
{
    // Assertion of the input parameters.
    ASSERT( uchType >= MEM_PROGRAM && uchType <= MEM_BIT );
    
    // Set server flag.
    m_isServer = TRUE;

    // Set address.
    m_StartAddr = CMemoryAddr(uStart, uchType);
    m_EndAddr = CMemoryAddr(uEnd, uchType);

    // Set pattern.
    SetPattern(pszPattern);
    
    // Memory Fill kernel routine.
    MemoryFillKernel();
    
}   // End of CMemoryFill::MemServerFill().

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