
/***************************************************************************
**
**    $Header:   D:/ECB2S/SRC/LOG/EMUPATCH.CPP   1.2.1.5   17 Apr 1997 15:48:42   ZJRD  $
**
**    $Log:   D:/ECB2S/SRC/LOG/EMUPATCH.CPP  $
** 
**    Rev 1.2.1.5   17 Apr 1997 15:48:42   ZJRD
** No change.
** 
**    Rev 1.2.1.4   16 Apr 1997 10:20:02   ZJRD
** No change.
** 
**    Rev 1.2.1.3   10 Apr 1997 15:31:26   ZJRD
** 2.09F
** 
**    Rev 1.2.1.1   03 Apr 1997 15:12:14   ZJRD
** No change.
** 
**    Rev 1.2.1.0   28 Mar 1997 10:17:14   ZJRD
** easy pack sld 2.09d
** 
**    Rev 1.1   19 Mar 1997 11:28:22   ZJRD
** No change.
** 
**    Rev 1.0   12 Mar 1997 14:46:08   ZJRD
** Initial revision.
** 
**    Rev 1.7.1.0.1.2   09 Dec 1996 10:14:52   ZJRD
** EasyPack/SLD Version 2.0P
** 
**    Rev 1.7.1.0.1.0   11 Nov 1996 12:58:08   ZJRD
** EasyPack/SLD Version 2.01
** 
**    Rev 1.7.1.4   09 Sep 1996 13:15:08   ZJRD
** No change.
** 
**    Rev 1.7.1.3   05 Sep 1996 11:26:40   ZJRD
** No change.
** 
**    Rev 1.7.1.2   02 Sep 1996 09:53:46   ZJRD
** No change.
** 
**    Rev 1.7.1.1   28 Aug 1996 15:47:22   ZJRD
** No change.
** 
**    Rev 1.7.1.0   12 Aug 1996 10:52:08   ZJRD
** EasyPack/SLD Version 1.98
** 
**    Rev 1.5   05 Jun 1996 14:55:28   ZJRD
** No change.
** 
**    Rev 1.4   29 May 1996 09:38:06   ZJRD
** No change.
** 
**    Rev 1.3   16 May 1996 09:00:24   ZJRD
** No change.
** 
**    Rev 1.2   10 May 1996 09:14:48   ZJRD
** No change.
** 
**    Rev 1.1   02 May 1996 10:22:40   ZJRD
** EasyPack/SLD Version 1.92
** 
**    Rev 1.31   18 Apr 1996 13:02:26   Shirley
** No change.
** 
**    Rev 1.30   12 Apr 1996 10:41:18   Shirley
** No change.
** 
**    Rev 1.29   02 Apr 1996 09:30:16   Shirley
** No change.
** 
**    Rev 1.28   15 Feb 1996 08:56:18   Shirley
** No change.
** 
**    Rev 1.27   12 Feb 1996 14:07:36   Shirley
** No change.
** 
**    Rev 1.26   06 Feb 1996 15:34:02   Shirley
** No change.
** 
**    Rev 1.25   06 Feb 1996 13:47:58   Shirley
** No change.
** 
**    Rev 1.24   01 Feb 1996 10:19:12   Shirley
** No change.
** 
**    Rev 1.23   26 Jan 1996 09:14:24   Shirley
** No change.
** 
**    Rev 1.22   25 Jan 1996 13:14:18   Shirley
** No change.
** 
**    Rev 1.21   24 Jan 1996 10:33:12   Shirley
** No change.
** 
**    Rev 1.20   23 Jan 1996 11:26:56   Shirley
** No change.
** 
**    Rev 1.19   18 Jan 1996 10:11:44   Shirley
** No change.
** 
**    Rev 1.18   15 Jan 1996 16:13:18   Shirley
** No change.
** 
**    Rev 1.17   04 Jan 1996 11:11:24   Shirley
** No change.
** 
**    Rev 1.16   30 Nov 1995 09:08:50   Shirley
** No change.
** 
**    Rev 1.15   28 Nov 1995 15:31:38   Shirley
** No change.
** 
**    Rev 1.14   21 Nov 1995 11:18:18   Shirley
** No change.
** 
**    Rev 1.13   13 Nov 1995 09:24:00   Shirley
** No change.
** 
**    Rev 1.12   12 Nov 1995 11:28:16   Shirley
** No change.
** 
**    Rev 1.11   08 Nov 1995 16:29:04   Shirley
** No change.
** 
**    Rev 1.10   08 Nov 1995 12:41:36   Shirley
** No change.
** 
**    Rev 1.9   02 Nov 1995 10:07:20   Shirley
** No change.
** 
**    Rev 1.8   27 Oct 1995 16:46:56   Shirley
** No change.
** 
**    Rev 1.7   27 Oct 1995 13:48:08   Shirley
** No change.
** 
**    Rev 1.6   25 Oct 1995 14:29:24   Shirley
** No change.
** 
**    Rev 1.5   18 Oct 1995 14:50:56   Shirley
** No change.
** 
**    Rev 1.4   13 Oct 1995 13:21:48   Shirley
** No change.
** 
**    Rev 1.3   29 Sep 1995 09:52:06   Shirley
** No change.
** 
**    Rev 1.2   20 Sep 1995 10:54:12   Shirley
** EasyPack/SLD Version 0.1b
** 
**    Rev 1.1   15 Sep 1995 09:45:38   Shirley
** No change.
** 
**    Rev 1.0   07 Sep 1995 09:55:42   Shirley
** Initial revision.
**
****************************************************************************/

/////////////////////////////////////////////////////////////////////////////
//
//  File name: EMUPATCH.CPP
//
//  Description: The implementation file for the class: CEmulationPatch & 
//               CPatchData. Meanwhile, the global object "PatchData" has
//               been created.
//
//  Author: Chen Jun
//
//  Date: 05/08/95
//
//  Modification:
//      1. 05/08/95, Initial version of the class: CEmulationPatch.
//      2. 05/08/95, Initial version of the class: CPatchData.
//
/////////////////////////////////////////////////////////////////////////////


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

#include "emupatch.h"


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


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


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


/////////////////////////////////////////////////////////////////////////////
// Global variables.
CPatchData PatchData;   // It will be used in EMUGO.CPP


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


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


/////////////////////////////////////////////////////////////////////////////
// Global function prototypes.
void PatchCmd(int nArgc, char* pszArgv[]);


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


/////////////////////////////////////////////////////////////////////////////
// External function prototypes.
#ifndef _SERVER_NO_ABI
    // No related ABI routine.
#endif  // _SERVER_NO_ABI



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

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

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   PatchCmd().
//
//  Description: The main control routine of Patch command.
//
//  Input:  nArgc - Number of input parameters.
//          pszArgv - Input parameters.
//
//  Output: None.
//
//  Return: None.
//
/////////////////////////////////////////////////////////////////////////////
void PatchCmd(int nArgc, char* pszArgv[])
{
    // Assertion of the input parameters.
    ASSERT( nArgc >= 1 && nArgc <= 6 && 4 != nArgc );
    for ( int i = 0; i < nArgc; i++ ) {
        ASSERT( pszArgv[i] );
    }
    
    // Execute Patch command.
    CEmulationPatch* pEmulationPatch = new CEmulationPatch;
    if ( !pEmulationPatch ) {
        AfxMessageBox("Insufficient Memory !");
        ASSERT( FALSE );
        return;
    }
    else {
        pEmulationPatch->PatchAction(nArgc, pszArgv);
        delete pEmulationPatch;
    }

//    CEmulationPatch objPatch;
//    objPatch.PatchAction(nArgc, pszArgv);

}   // End of PatchCmd().



/////////////////////////////////////////////////////////////////////////////
// Implementation codes of class: CEmulationPatch.

// Construction.
CEmulationPatch::CEmulationPatch()
{

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


// Destruction.
CEmulationPatch::~CEmulationPatch()
{

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


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

    // Set the parameters.
    switch ( nArgc ) {
        case 1:
            // Patch
            DisplayPatch();
            break;
        case 2:
            // Patch CLear
            SetAddrVar(MEM_UNDEFINE, 0, m_Addr1);
            SetAddrVar(MEM_UNDEFINE, 0, m_Addr2);
            SetAddrVar(MEM_UNDEFINE, 0, m_Addr3);
            SetAddrVar(MEM_UNDEFINE, 0, m_Addr4);
            break;
        case 3:
            // Patch adr1 adr2
            SetAddrVar(pszArgv[1], m_Addr1);
            SetAddrVar(pszArgv[2], m_Addr2);
            SetAddrVar(MEM_UNDEFINE, 0, m_Addr3);
            SetAddrVar(MEM_UNDEFINE, 0, m_Addr4);
            break;
        case 5:
            // Patch adr1 With adr3 adr4
            SetAddrVar(pszArgv[1], m_Addr1);
            SetAddrVar(MEM_UNDEFINE, 0, m_Addr2);
            SetAddrVar(pszArgv[3], m_Addr3);
            SetAddrVar(pszArgv[4], m_Addr4);
            break;
        case 6:
            // Patch adr1 adr2 With adr3 adr4
            SetAddrVar(pszArgv[1], m_Addr1);
            SetAddrVar(pszArgv[2], m_Addr2);
            SetAddrVar(pszArgv[4], m_Addr3);
            SetAddrVar(pszArgv[5], m_Addr4);
            break;
        default:
            ASSERT( FALSE );
            break;
    }
    
    // Call Patch kernel.
    if ( 1 != nArgc ) {
        PatchKernel();
    }
    
}   // End of CEmulationPatch::PatchAction().


// Patch kernel routine.
void CEmulationPatch::PatchKernel(void)
{
    // Assertion of the input parameters.
    ASSERT(MEM_UNDEFINE==m_Addr1.m_uchType||MEM_PROGRAM==m_Addr1.m_uchType);
    ASSERT(MEM_UNDEFINE==m_Addr2.m_uchType||MEM_PROGRAM==m_Addr2.m_uchType);
    ASSERT(MEM_UNDEFINE==m_Addr3.m_uchType||MEM_PROGRAM==m_Addr3.m_uchType);
    ASSERT(MEM_UNDEFINE==m_Addr4.m_uchType||MEM_PROGRAM==m_Addr4.m_uchType);
    
    // Set the Patch data to the global variable.
    SetPatchData();
    
    // Show the patch setting.
    DisplayPatch();
    
}   // End of CEmulationPatch::PatchKernel().


// Display patch setting.
void CEmulationPatch::DisplayPatch(void)
{
    // Assertion of the input parameters.
    
    // Get the current Patch setting.
    GetPatchData();
    
    // Test parameters.
    //DumpVar(m_Addr1.m_uchType);
    //DumpVar(m_Addr2.m_uchType);
    //DumpVar(m_Addr3.m_uchType);
    //DumpVar(m_Addr4.m_uchType);
    
    //DumpVar((unsigned long)m_Addr1.m_uAddr);
    //DumpVar((unsigned long)m_Addr2.m_uAddr);
    //DumpVar((unsigned long)m_Addr3.m_uAddr);
    //DumpVar((unsigned long)m_Addr4.m_uAddr);

    // Format the message string.
    if ( MEM_UNDEFINE == m_Addr1.m_uchType ) {
        // Patch is clear.
        ASSERT( MEM_UNDEFINE == m_Addr1.m_uchType);
        ASSERT( MEM_UNDEFINE == m_Addr2.m_uchType);
        ASSERT( MEM_UNDEFINE == m_Addr3.m_uchType);
        ASSERT( MEM_UNDEFINE == m_Addr4.m_uchType);
        wsprintf(m_pszResult, "Patch is clear.");
    }
    else if ( MEM_UNDEFINE == m_Addr3.m_uchType ) {
        // Skip codes.
        ASSERT( MEM_PROGRAM == m_Addr1.m_uchType);
        ASSERT( MEM_PROGRAM == m_Addr2.m_uchType);
        unsigned short uAddr = max(m_Addr1.m_uAddr, (m_Addr2-1).m_uAddr);
        if ( 0 == m_Addr2.m_uAddr ) {
            uAddr = 0;
        }
        wsprintf(m_pszResult, "Skip codes (P:%04X - P:%04X).",
                 m_Addr1.m_uAddr, uAddr);
    }
    else if ( MEM_UNDEFINE == m_Addr2.m_uchType ) {
        // Insert codes.
        ASSERT( MEM_PROGRAM == m_Addr1.m_uchType);
        ASSERT( MEM_PROGRAM == m_Addr3.m_uchType);
        ASSERT( MEM_PROGRAM == m_Addr4.m_uchType);
        unsigned short uAddr = max(m_Addr3.m_uAddr, (m_Addr4-1).m_uAddr);
        if ( 0 == m_Addr4.m_uAddr ) {
            uAddr = 0;
        }
        wsprintf(m_pszResult, "Insert codes (P:%04X - P:%04X) at P:%04X.",
                 m_Addr3.m_uAddr, uAddr, m_Addr1.m_uAddr);
    }
    else {
        // Replace codes.
        ASSERT( MEM_PROGRAM == m_Addr1.m_uchType);
        ASSERT( MEM_PROGRAM == m_Addr2.m_uchType);
        ASSERT( MEM_PROGRAM == m_Addr3.m_uchType);
        ASSERT( MEM_PROGRAM == m_Addr4.m_uchType);
        unsigned short uAddr1 = max(m_Addr1.m_uAddr, (m_Addr2-1).m_uAddr);
        if ( 0 == m_Addr2.m_uAddr ) {
            uAddr1 = 0;
        }
        unsigned short uAddr2 = max(m_Addr3.m_uAddr, (m_Addr4-1).m_uAddr);
        if ( 0 == m_Addr4.m_uAddr ) {
            uAddr2 = 0;
        }
        wsprintf(m_pszResult, 
            "Replace codes (P:%04X - P:%04X) by codes (P:%04X - P:%04X).",
            m_Addr1.m_uAddr, uAddr1, m_Addr3.m_uAddr, uAddr2);
    }

    // Show the message.
    ShowLine(m_pszResult);

}   // End of CEmulationPatch::DisplayPatch().


// Set Patch to the global variable.
void CEmulationPatch::SetPatchData(void) const
{
    // Assertion of the input parameters.
    ASSERT(MEM_UNDEFINE==m_Addr1.m_uchType||MEM_PROGRAM==m_Addr1.m_uchType);
    ASSERT(MEM_UNDEFINE==m_Addr2.m_uchType||MEM_PROGRAM==m_Addr2.m_uchType);
    ASSERT(MEM_UNDEFINE==m_Addr3.m_uchType||MEM_PROGRAM==m_Addr3.m_uchType);
    ASSERT(MEM_UNDEFINE==m_Addr4.m_uchType||MEM_PROGRAM==m_Addr4.m_uchType);
    
    // Write the global variable.
    ::PatchData.SetPatchData(m_Addr1, m_Addr2, m_Addr3, m_Addr4);

}   // End of CEmulationPatch::SetPatchData().


// Get Patch from the global variable.
void CEmulationPatch::GetPatchData(void)
{
    // Assertion of the input parameters.
    
    // Read the global variable.
    ::PatchData.GetPatchData(m_Addr1, m_Addr2, m_Addr3, m_Addr4);

}   // End of CEmulationPatch::SetPatchData().




/////////////////////////////////////////////////////////////////////////////
// Implementation codes of class: CPatchData.

// Construction.
CPatchData::CPatchData()
{
    // Assertion of the input parameters.
    
    // Initialization.
    CMemoryAddr Addr;
    SetAddrVar(MEM_UNDEFINE, 0, Addr);
    
    m_Addr1 = Addr;
    m_Addr2 = Addr;
    m_Addr3 = Addr;
    m_Addr4 = Addr;

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


// Destruction.
CPatchData::~CPatchData()
{

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


// Set the Patch data.
void CPatchData::SetPatchData(const CMemoryAddr Addr1, const CMemoryAddr Addr2,
                              const CMemoryAddr Addr3, const CMemoryAddr Addr4)
{
    // Assertion of the input parameters.
    ASSERT( MEM_UNDEFINE==Addr1.m_uchType || MEM_PROGRAM==Addr1.m_uchType );
    ASSERT( MEM_UNDEFINE==Addr2.m_uchType || MEM_PROGRAM==Addr2.m_uchType );
    ASSERT( MEM_UNDEFINE==Addr3.m_uchType || MEM_PROGRAM==Addr3.m_uchType );
    ASSERT( MEM_UNDEFINE==Addr4.m_uchType || MEM_PROGRAM==Addr4.m_uchType );
    
    // Set to the golbal variables.
    m_Addr1 = Addr1;
    m_Addr2 = Addr2;
    m_Addr3 = Addr3;
    m_Addr4 = Addr4;

}   // End of CPatchData::SetPatchData().
                              

// Get the Patch data.
void CPatchData::GetPatchData(CMemoryAddr& Addr1, CMemoryAddr& Addr2,
                              CMemoryAddr& Addr3, CMemoryAddr& Addr4) const
{
    // Assertion of the input parameters.
    ASSERT(MEM_UNDEFINE==m_Addr1.m_uchType||MEM_PROGRAM==m_Addr1.m_uchType);
    ASSERT(MEM_UNDEFINE==m_Addr2.m_uchType||MEM_PROGRAM==m_Addr2.m_uchType);
    ASSERT(MEM_UNDEFINE==m_Addr3.m_uchType||MEM_PROGRAM==m_Addr3.m_uchType);
    ASSERT(MEM_UNDEFINE==m_Addr4.m_uchType||MEM_PROGRAM==m_Addr4.m_uchType);
    
    // Set to the golbal variables.
    Addr1 = m_Addr1;
    Addr2 = m_Addr2;
    Addr3 = m_Addr3;
    Addr4 = m_Addr4;

}   // End of CPatchData::SetPatchData().
                              

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