/***************************************************************************
**
**    $Header:   D:/ECB2S/SRC/LOG/ADDRAPI.CPP   1.2.1.5   17 Apr 1997 15:40:56   ZJRD  $
**
**    $Log:   D:/ECB2S/SRC/LOG/ADDRAPI.CPP  $
** 
**    Rev 1.2.1.5   17 Apr 1997 15:40:56   ZJRD
** No change.
** 
**    Rev 1.2.1.4   16 Apr 1997 10:11:12   ZJRD
** No change.
** 
**    Rev 1.2.1.3   10 Apr 1997 15:26:42   ZJRD
** 2.09F
** 
**    Rev 1.2.1.1   03 Apr 1997 15:08:48   ZJRD
** No change.
** 
**    Rev 1.2.1.0   28 Mar 1997 10:13:46   ZJRD
** easy pack sld 2.09d
** 
**    Rev 1.1   19 Mar 1997 11:25:06   ZJRD
** No change.
** 
**    Rev 1.0   12 Mar 1997 14:44:14   ZJRD
** Initial revision.
** 
**    Rev 1.7.1.0.1.2   09 Dec 1996 10:15:24   ZJRD
** EasyPack/SLD Version 2.0P
** 
**    Rev 1.7.1.0.1.0   11 Nov 1996 12:58:42   ZJRD
** EasyPack/SLD Version 2.01
**                                                 
**    Rev 1.7.1.4   09 Sep 1996 13:16:26   ZJRD
** No change.
** 
**    Rev 1.7.1.3   05 Sep 1996 11:27:58   ZJRD
** No change.
** 
**    Rev 1.7.1.2   02 Sep 1996 09:55:04   ZJRD
** No change.
** 
**    Rev 1.7.1.1   28 Aug 1996 15:50:34   ZJRD
** No change.
** 
**    Rev 1.7.1.0   12 Aug 1996 10:54:30   ZJRD
** EasyPack/SLD Version 1.98
** 
**    Rev 1.7   11 Jun 1996 10:28:54   ZJRD
** EasyPack/SLD Version 1.97
** 
**    Rev 1.5   05 Jun 1996 14:57:32   ZJRD
** No change.
** 
**    Rev 1.4   29 May 1996 09:35:14   ZJRD
** EasyPack/SLD Version 1.95
** 
**    Rev 1.3   16 May 1996 09:08:18   ZJRD
** EasyPack/SLD Version 1.94
** 
**    Rev 1.2   10 May 1996 09:16:46   ZJRD
** EasyPack/SLD Version 1.93
** 
**    Rev 1.1   02 May 1996 10:31:08   ZJRD
** EasyPack/SLD Version 1.92
** 
**    Rev 1.1   18 Apr 1996 12:56:24   Shirley
** EasyPack/SLD Version 1.91
** 
**    Rev 1.0   12 Apr 1996 10:35:54   Shirley
** Initial revision.
** 
****************************************************************************/

/****************************************************************************
**
**  Name:      Addrapi.cpp
**
**  Description: Main file of the address server API
**               Only for 51 base family CPU
**
**  Status: Initialization
**          1996/03/05        Daniel Lin
**
**  Copyright (C) 1996 Microtek International.  All rights reserved.
******************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#include "stdafx.h"
#include "address.h"                // Include main head file
#include "addrapi.h"                // Include API main head

// include error handling head file
//
#include "errcodec.h"                   
#include "dad.h"                   
#include "cpucom.h"
#include "cpuserve.h"               // Include CPU server for GetMemoryRange()

                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
                        ****************************/
extern ADDR_SIZE  dwpMax;        // program  max address
extern ADDR_SIZE  dwpMin;        // program  min address
extern ADDR_SIZE  dwxMax;        // external max address
extern ADDR_SIZE  dwxMin;        // external min address
extern ADDR_SIZE  dwiMax;        // internal max address
extern ADDR_SIZE  dwiMin;        // internal min address
extern ADDR_SIZE  dwrMax;        // SFR max address
extern ADDR_SIZE  dwrMin;        // SFR min address
extern ADDR_SIZE  dwbMax;        // bit max address
extern ADDR_SIZE  dwbMin;        // bit min address

//extern CPUMEMORYRANGE;   
extern int GetMemoryRange(CPUMEMORYRANGE* stRange); 
extern RETCODE EXPORT ErrGetErrorText(U32 errorCode, LPSTR lpszError ...);
extern RETCODE EXPORT ErrGetErrorText(U32 errorCode, CString& strError ...);
void ShowLine(char* pszBuffer);

                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/
static   char  *SpaceString[] =
               {
                  "", "P:", "X:", "I:", "R:", "B:", "P0:", "P1:", "P2:", 
                  "P3:", 
               };

                       /****************************
                        *                          *
                        *       GLOBAL VARS        *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *     LOCAL PROTOTYPES     *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *      EXECUTABLE CODE     *
                        *                          *
                        ****************************/

/**----------------------------------------------------------------------
 **   AdrAddrToHex
 **
 **   addr        Set to the address.
 **   adrstr      Set to the converted address text string .
 **
 **   Remark
 **      Call this function to convert an address to text string. The
 **      address descripted by the ADDRESS struct.
 **      If there is no space, the adrSpace must set to 51SPACE_UNDEFINE.
 **      The result hex string hasn't any leading zero.
 **
 **   Return value
 **      One of the enum of ADDR_RETCODE.
 **      If this return value equal to ADR_OK, the convert is successful.
 **      The second parameter -- adrstr will be changed to the hex address
 **      string if convert is successful. Otherwise, the adrstr will not
 **      be changed
 **
 **      (See the defination of the ADDR_RETCODE)
 **
 **      Examples
 **         char         strTemp[150];
 **         ADDR_RETCODE retCode;
 **         ADDRESS      address;
 **
 **         address.adrSpace = SPACE_PROGRAM;
 **         address.address = 100;
 **         retCode = AdrAddrToHex(address, strTemp);
 **         if (ADR_OK == retCode)
 **             // The convert is successful. The address is correct.
 **         else
 **             // The convert is failure. The address has some error
 **
 **         The address of 100 in program area will be converted to the
 **         hex text string strTemp. The parameter strTemp is change to
 **         "P:0x64".
 **----------------------------------------------------------------------*/
ADDR_RETCODE
AdrAddrToHex( const ADDRESS   addr,  LPSTR    adrstr )
{
   ASSERT(NULL != adrstr);

   C51Address  address(addr);
   CString     adr = "";
   ADDR_SPACE  space = SPACE_UNDEFINE;
   BOOL        bIsOk = FALSE;

   bIsOk = address.ConvertCheck();
   if (bIsOk) {
      adr = address.GetHexAddr();
      space = address.GetSpace();
      if (SPACE_UNDEFINE != space) {
         lstrcpy(adrstr, SpaceString[space]);
         char *temp = new char[adr.GetLength()+1];
         ASSERT(NULL != temp);
         lstrcpy(temp, adr.GetBuffer(adr.GetLength()));
		 if ( space >= SPACE_BANK1 ) {
			lstrcpy(adrstr+3, temp);		 
		 }
		 else {	         
         	lstrcpy(adrstr+2, temp);
         }	
         delete []temp;
      }
      else
         lstrcpy(adrstr, adr.GetBuffer(adr.GetLength()));   
   }
   
   return address.GetRetCode();
}

ADDR_RETCODE
AdrAddrToHex( const ADDRESS   addr,  CString  &adrstr )
{
   ASSERT("" != adrstr);

   C51Address  address(addr);
   CString     adr = "";
   ADDR_SPACE  space = SPACE_UNDEFINE;
   BOOL        bIsOk = FALSE;

   bIsOk = address.ConvertCheck();
   if (bIsOk) {
      adr = address.GetHexAddr();
      space = address.GetSpace();
      if (SPACE_UNDEFINE != space) {
         adrstr = SpaceString[space];
         adrstr += adr;
      }
      else
         adrstr = adr;
   }      
   
   return address.GetRetCode();
}  // End of AdrAddrToHex()
                                          
                                          
//for Dad to show Assemble address
ADDR_RETCODE AdrDadAddrToHex( const ADDRESS   addr,  CString  &adrstr )
{
   C51Address  address(addr);
   CString     adr = "";                             
   CString	   strTemp = "";	
   ADDR_SPACE  space = SPACE_UNDEFINE;
   BOOL        bIsOk = FALSE;

   bIsOk = address.ConvertCheck();
   if (bIsOk) {
      adr = address.GetHexAddr();
      space = address.GetSpace();

      if (SPACE_UNDEFINE != space) {
         adrstr = SpaceString[space];
	  	 strTemp = adr.Right(adr.GetLength()-2);
	  	 int nLen = strTemp.GetLength();
	  	 if ( nLen != 4) { 
			//adrstr = "";
	  	 	for ( int i=0; i<(4-nLen); i++ ) {
	  	 		adrstr += '0';
	  	 	}	           
	  	 	adrstr += strTemp;
	  	 }
	  	 else {
	  	 	adrstr += strTemp;
	  	 }
	  	 adrstr.MakeUpper();      	          
      }
      else
         adrstr = adr;
   }      
   
   return address.GetRetCode();
}  // End of AdrDadAddrToHex()


ADDR_RETCODE AdrDadAddrToHex( const ADDRESS   addr,  LPSTR    adrstr )
{
   ASSERT(NULL != adrstr);

   C51Address  address(addr);
   CString     adr = "";
   CString     strTemp1 = "";
   CString     strTemp = "";
   ADDR_SPACE  space = SPACE_UNDEFINE;
   BOOL        bIsOk = FALSE;   

   bIsOk = address.ConvertCheck();
   if (bIsOk) {
      adr = address.GetHexAddr();
      space = address.GetSpace();
      if (SPACE_UNDEFINE != space) {
         strTemp1 = SpaceString[space];
	  	 strTemp = adr.Right(adr.GetLength()-2);
	  	 int nLen = strTemp.GetLength();
	  	 if ( nLen != 4) { 
			//adrstr = "";
	  	 	for ( int i=0; i<(4-nLen); i++ ) {
	  	 		strTemp1 += '0';
	  	 	}	           
	  	 	strTemp1 += strTemp;
	  	 }
	  	 else {
	  	 	strTemp1 += strTemp;
	  	 }
	  	 strTemp1.MakeUpper();      	          
      }
      else
         strTemp1 = adr;
   }      

   strcpy(adrstr, strTemp1); 	   
   return address.GetRetCode();
}

                                          

/**----------------------------------------------------------------------
 **   AdrAddrToDec
 **
 **   addr     Set to the address.
 **   adrstr   Set to the converted address dec text string .
 **
 **   Remark
 **   Call this function to convert an address to dec text string. The space
 **   style's string will add to the front of the address's string.
 **   The converted address text string will store in the third parameter
 **   (adrstr).
 **   If there is no space, the adrSpace must set to 51SPACE_UNDEFINE.
 **   The result hex string hasn't any leading zero.
 **
 **   Return value
 **   One of the enum of ADDR_RETCODE.
 **   If this return value equal to ADR_OK, the convert is successful.
 **   (See the defination of the ADDR_RETCODE)
 **
 **   Examples
 **      char         strTemp[150];
 **      ADDR_RETCODE retCode;
 **      ADDRESS      address;
 **
 **      address.adrSpace = SPACE_PROGRAM;
 **      address.address = 100;
 **      retCode = AdrAddrToDec(address, strTemp);
 **      if (ADR_OK == retCode)
 **         // The convert is successful. The address is correct.
 **      else
 **         // The convert is failure. The address has some error
 **
 **   The address of 100 in program area will be converted to the hex text
 **   string strTemp. The parameter strTemp is change to "P:100
 **
 **----------------------------------------------------------------------*/
ADDR_RETCODE
AdrAddrToDec( const ADDRESS   addr, LPSTR adrstr )
{
   ASSERT(NULL != adrstr);

   C51Address  address(addr);
   CString     adr = "";
   ADDR_SPACE  space = SPACE_UNDEFINE;
   BOOL        bIsOk = FALSE;

   bIsOk = address.ConvertCheck();
   if (bIsOk) {
      adr = address.GetDecAddr();
      space = address.GetSpace();
      if (SPACE_UNDEFINE != space) {
         lstrcpy(adrstr, SpaceString[space]);
         char *temp = new char[adr.GetLength()+1];
         ASSERT(NULL != temp);
         lstrcpy(temp, adr.GetBuffer(adr.GetLength()));
		 if ( space >= SPACE_BANK1 ) {
			lstrcpy(adrstr+3, temp);		 
		 }
		 else {	       
         	lstrcpy(adrstr+2, temp);
         }	
         delete []temp;
      }
      else
         lstrcpy(adrstr, adr.GetBuffer(adr.GetLength()));   
   }
   
   return address.GetRetCode();
}

ADDR_RETCODE
AdrAddrToDec( const ADDRESS   addr, CString &adrstr )
{
   ASSERT("" != adrstr);

   C51Address  address(addr);
   CString     adr = "";
   ADDR_SPACE  space = SPACE_UNDEFINE;
   BOOL        bIsOk = FALSE;

   bIsOk = address.ConvertCheck();
   if (bIsOk) {
      adr = address.GetDecAddr();
      space = address.GetSpace();
      if (SPACE_UNDEFINE != space) {
         adrstr = SpaceString[space];
         adrstr += adr;
      }
      else
         adrstr = adr;
   }      
   
   return address.GetRetCode();
}  // End of AdrAddrToDec()


/**----------------------------------------------------------------------
 **   AdrTextToAddr
 **
 **   adrstr  Set to the address text string;
 **   addr    Set to the return address(converted address)
 **
 **   Remark
 **   Call this function to convert a hex address text string.
 **   The converted address store in the second parameter(addr).
 **   The address text string will set to hex string or dec string.
 **   Distinguish the two string by the leading char "0x".
 **
 **   Return value
 **   One of the enum of ADDR_RETCODE.
 **   If this return value equal to ADR_OK, the convert is successful.
 **   (See the defination of the ADDR_RETCODE).
 **
 **   If the address text string soesn't include any space, the field
 **   in ADDRESS (adrSpace) will set to SPACE_UNDEFINE.
 **
 **   Examples
 **       char            *adrStr = "r:0x64";
 **       ADDRESS         address;
 **       ADDR_RETCODE    retCode;
 **
 **       retCode = AdrTextToAddr(adrstr, address);
 **       if (ADR_OK == retCode)
 **           // The convert is successful. The address is correct.
 **       else
 **           // The convert is failure. The address has some error
 **
 **----------------------------------------------------------------------*/
ADDR_RETCODE
AdrTextToAddr(const LPSTR  adrstr, ADDRESS &addr, UINT isHex)
{  
   C51Address  address(adrstr, isHex);
   BOOL        bIsOk = FALSE;
   
   bIsOk = address.ConvertCheck();
   if (bIsOk) {
      addr.adrSpace = address.GetSpace();    
/*
      if (addr.adrSpace == SPACE_PROGRAME) {
			addr.adrSpace = ADDR_SPACE(GetCurrentBank());      
      }
*/
      addr.adrAddress = address.GetAddress();
   }

   return address.GetRetCode();
}


ADDR_RETCODE
AdrTextToAddr(const CString& adrstr, ADDRESS &addr, UINT isHex)
{  
   C51Address  address(adrstr, isHex);
   BOOL        bIsOk = FALSE;

   bIsOk = address.ConvertCheck();
   if (bIsOk) {
      addr.adrSpace = address.GetSpace();
/*
      if (addr.adrSpace == SPACE_PROGRAME) {
			addr.adrSpace = ADDR_SPACE(GetCurrentBank());      
      }
*/
      addr.adrAddress = address.GetAddress();
   }

   return address.GetRetCode();
}  // End of AdrTextToAddr()


///////////////////////////////////////////////////////////////////////
// AdrShellToAddr
//    Only for shell window
//    The third parameter is a space define(default is data area)
//
ADDR_RETCODE
AdrShellToAddr(const CString& adrstr, ADDRESS &addr, ADDR_SPACE Space)
{
   ADDR_RETCODE retCode;
   
   retCode = AdrTextToAddr(adrstr, addr, 1);    // Convert as address
   if (ADR_OK == retCode) {
      if (SPACE_UNDEFINE == addr.adrSpace) {
         if ( Space != SPACE_PROGRAME ) {
         	addr.adrSpace = Space;           // Set to default space
         }
         else { 
         	if ( g_nBankNum != 0 ) {
       			addr.adrSpace = SPACE_BANK1;
       		}
       		else {
       			addr.adrSpace = SPACE_PROGRAME;
       		} 	
         }	                                
      }   
   }
   
   return retCode;
}

ADDR_RETCODE
AdrShellToAddr(const LPSTR  adrstr, ADDRESS &addr, ADDR_SPACE Space)
{
   ADDR_RETCODE retCode;
   
   retCode = AdrTextToAddr(adrstr, addr, 1);    // Convert as address
   if (ADR_OK == retCode) {
      if (SPACE_UNDEFINE == addr.adrSpace) {
         if ( Space != SPACE_PROGRAME ) {
         	addr.adrSpace = Space;           // Set to default space
         }
         else {
         	if ( g_nBankNum != 0 ) {
       			addr.adrSpace = SPACE_BANK1;
       		}
       		else {
       			addr.adrSpace = SPACE_PROGRAME;
       		} 	
         }	                                
      }   
   }
   
   return retCode;
}

/**----------------------------------------------------------------------
 **   AdrAddrToSymbol
 **
 **   Symbol  Set to the symbol text string converted from the addr;
 **   addr    Set to the address will be converted
 **
 **   Remark
 **   Call this function to convert a address to a symbol text string.
 **   The Symbol will support the format as "#ModuleName#SymbolName".
 **   This function will call Symbol server.
 **
 **   Return value
 **   True if convert successful.
 **
 **   Examples
 **       CString     sybStr;
 **       ADDRESS     addr;
 **       BOOL        bOk = FALSE;
 **       
 **       addr.adrSpace = ADR_PROGRAME;
 **       addr.adrAddress = 0xFFFF;  
 **       bOk = AdrAddrToSymbol(addr, sybStr);
 **
 **----------------------------------------------------------------------*/
 
BOOL
AdrAddrToSymbol(const ADDRESS &addr, LPSTR symbol)
{
   // Add AddrToSymbol() by Symbol server
   //            
   if (AddrToSym(addr.adrSpace, addr.adrAddress, symbol) != GOOD) {
   	return FALSE;			
   }               
   else {   
   	return TRUE;                 //   address.GetRetCode();
   }	
}

BOOL
AdrAddrToSymbol(const ADDRESS &addr, CString& symbol)
{
   // Add AddrToSymbol() by Symbol server
   //
	char chSymbol[256];   
   if (AddrToSym(addr.adrSpace, addr.adrAddress, chSymbol) != GOOD) {
   	return FALSE;			
   }               
   else {                                             
   	symbol = chSymbol;
   	return TRUE;                 //   address.GetRetCode();
   }	
}  // End of AdrAddrToSymbol()


/**---------------------------------------------------------------------
 **   AdrCheckAddrRange
 **
 **   address     Set to the address
 **   
 **   Remark
 **   Call this function to check the address range
 **
 **---------------------------------------------------------------------*/

BOOL
AdrCheckAddrRange(ADDRESS address)
{
   BOOL  bIsInRange = TRUE;
   
   switch(address.adrSpace) {
      case  SPACE_PROGRAME:
            if (dwpMin == dwpMax)
               bIsInRange = FALSE;
            else {   
               if (address.adrAddress > dwpMax ||
                   address.adrAddress < dwpMin)
                   bIsInRange = FALSE;
            }                   
            break;
            
      case  SPACE_INTERNAL:
            if (dwiMin == dwiMax)
               bIsInRange = FALSE;
            else {   
               if (address.adrAddress > dwiMax ||
                   address.adrAddress < dwiMin)
                   bIsInRange = FALSE;
            }                   
            break;
            
      case  SPACE_EXTERNAL:
            if (dwxMin == dwxMax)
               bIsInRange = FALSE;
            else {   
               if (address.adrAddress > dwxMax ||
                   address.adrAddress < dwxMin)
                   bIsInRange = FALSE;
            }                   
            break;
            
      case  SPACE_BIT:
            if (dwbMin == dwbMax)
               bIsInRange = FALSE;
            else {   
               if (address.adrAddress > dwbMax ||
                   address.adrAddress < dwbMin)
                   bIsInRange = FALSE;
            }                   
            break;
            
      case  SPACE_SFR:
            if (dwrMin == dwrMax)
               bIsInRange = FALSE;
            else {   
               if (address.adrAddress > dwrMax ||
                   address.adrAddress < dwrMin)
                   bIsInRange = FALSE;
            }                   
            break;

      case  SPACE_BANK1:
            if (dwpMin == dwpMax)
               bIsInRange = FALSE;
            else {   
               if (address.adrAddress > dwpMax ||
                   address.adrAddress < dwpMin)
                   bIsInRange = FALSE;
            }                   
            break;

      case  SPACE_BANK2:
            if (dwpMin == dwpMax)
               bIsInRange = FALSE;
            else {   
               if (address.adrAddress > dwpMax ||
                   address.adrAddress < dwpMin)
                   bIsInRange = FALSE;
            }                   
            break;

      case  SPACE_BANK3:
            if (dwpMin == dwpMax)
               bIsInRange = FALSE;
            else {   
               if (address.adrAddress > dwpMax ||
                   address.adrAddress < dwpMin)
                   bIsInRange = FALSE;
            }                   
            break;

      case  SPACE_BANK4:
            if (dwpMin == dwpMax)
               bIsInRange = FALSE;
            else {   
               if (address.adrAddress > dwpMax ||
                   address.adrAddress < dwpMin)
                   bIsInRange = FALSE;
            }                   
            break;

      default:
            if (address.adrAddress > 0xFFFF ||
                address.adrAddress < 0)
                bIsInRange = FALSE;
            break;
   }
   
   return bIsInRange;
}  // End of AdrCheckAddrRange()

/**----------------------------------------------------------------------
 **   AdrShlCheck2Addr
 **
 **   adrstr1     Set to the first address;
 **   adrstr2     Set to the second address;
 **   ADDR_SPACE  Set the default space
 **
 **   Remark
 **   Call this function to check two address. Only for shell window
 **   Check range
 **   No converting.
 **
 **   Return value
 **   One of the enum of ADDR_RETCODE.
 **   If this return value equal to ADR_OK, the convert is successful.
 **   (See the defination of the ADDR_RETCODE).
 **
 **----------------------------------------------------------------------*/
ADDR_RETCODE
AdrShlCheck2Addr(const LPSTR adrstr1, const LPSTR  adrstr2, ADDR_SPACE space)
{
   ADDRESS  address1, address2;
   ADDR_RETCODE   adrRet = ADR_OK;
   
   adrRet = AdrTextToAddr(adrstr1, address1);
   if (ADR_OK != adrRet) {
      CString error;
 	   AdrErrorDeal(adrRet, error);
 	   char* pszError = new char[error.GetLength()+2];
 	   strcpy(pszError, error);
 	   ShowLine(pszError);
 	   delete []pszError;
      return adrRet;      
   }   
   
   adrRet = AdrTextToAddr(adrstr2, address2);
   if (ADR_OK != adrRet) {
      CString error;
 	   AdrErrorDeal(adrRet, error);
 	   char* pszError = new char[error.GetLength()+2];
 	   strcpy(pszError, error);
 	   ShowLine(pszError);
 	   delete []pszError;
      return adrRet;
   }   
   adrRet = AdrShlCheck2Addr(address1, address2, space);
   if (ADR_OK != adrRet) {
      CString error;
 	   AdrErrorDeal(adrRet, error);
 	   char* pszError = new char[error.GetLength()+2];
 	   strcpy(pszError, error);
 	   ShowLine(pszError);
 	   delete []pszError;  
   }     
   
   return adrRet;
}

ADDR_RETCODE
AdrShlCheck2Addr(const CString& adrstr1, const CString& adrstr2, ADDR_SPACE space)
{
   ADDRESS  address1, address2;
   ADDR_RETCODE   adrRet = ADR_OK;

   adrRet = AdrTextToAddr(adrstr1, address1);
   if (ADR_OK != adrRet)
      return adrRet;
   adrRet = AdrTextToAddr(adrstr2, address2);
   if (ADR_OK != adrRet)
      return adrRet;
      
   adrRet = AdrShlCheck2Addr(address1, address2, space);
   return adrRet;
}

ADDR_RETCODE
AdrShlCheck2Addr(ADDRESS address1, ADDRESS address2, ADDR_SPACE space )
{
   ADDR_RETCODE   adrRet = ADR_OK;
   
   if ((SPACE_UNDEFINE == address1.adrSpace)
         &&(SPACE_UNDEFINE == address2.adrSpace)) {
		if ( space != SPACE_PROGRAME || g_nBankNum == 0)  {
	      address1.adrSpace = space;    // Set to default space
	      address2.adrSpace = space;    // Set to default space
	   }
	   else {
			address1.adrSpace = SPACE_BANK1;
			address2.adrSpace = SPACE_BANK2;
	   }   
   }
         
   if (SPACE_UNDEFINE != address2.adrSpace) {//address2 define space
      if ( address1.adrSpace < SPACE_BANK1 &&            
      	  address1.adrSpace != address2.adrSpace) {
         adrRet = ADR_COMPERROR;
         return adrRet;
      }                                       
      else {
      	if ( address1.adrSpace > address2.adrSpace ) {
	         adrRet = ADR_COMPERROR;
	         return adrRet;      	
      	}	
      }
   }
   else
     address2.adrSpace = address1.adrSpace;  //address2 undefine space
                                             // make address1 and 
                                             // address2 the same space

   if (!AdrCheckAddrRange(address1)) {
      adrRet = ADR_OUTRANGE;
      return adrRet;
   }   
   if (!AdrCheckAddrRange(address2)) {
      adrRet = ADR_OUTRANGE;   
      return adrRet;      
   }
	if (address1.adrSpace < SPACE_BANK1) {      
	   if (address1.adrAddress > address2.adrAddress)
	      adrRet = ADR_COMPERROR;
	   else
	      adrRet = ADR_OK;      
	}      
   else {
   	if ( address1.adrSpace < address2.adrSpace ) {
   		adrRet = ADR_OK;      	
   	}
   	else if (address1.adrSpace == address2.adrSpace) {
		   if (address1.adrAddress > address2.adrAddress)
		      adrRet = ADR_COMPERROR;
		   else
		      adrRet = ADR_OK;         	
   	}                           
   	else {
   		adrRet = ADR_COMPERROR;
   	}
   }
   return adrRet;
}  // End of AdrCheck2Addr()

/**----------------------------------------------------------------------
 **   AdrCheck2Addr
 **
 **   adrstr1     Set to the first address;
 **   adrstr2     Set to the second address;
 **
 **   Remark
 **   Call this function to check two address.
 **   Check range
 **   No converting.
 **
 **   Return value
 **   One of the enum of ADDR_RETCODE.
 **   If this return value equal to ADR_OK, the convert is successful.
 **   (See the defination of the ADDR_RETCODE).
 **
 **----------------------------------------------------------------------*/
ADDR_RETCODE
AdrCheck2Addr(const LPSTR adrstr1, const LPSTR  adrstr2)
{
   ADDRESS  address1, address2;
   ADDR_RETCODE   adrRet = ADR_OK;

   adrRet = AdrTextToAddr(adrstr1, address1);
   if (ADR_OK != adrRet)
      return adrRet;
   adrRet = AdrTextToAddr(adrstr2, address2);
   if (ADR_OK != adrRet)
      return adrRet;

   adrRet = AdrCheck2Addr(address1, address2);
   return adrRet;
}

ADDR_RETCODE
AdrCheck2Addr(const CString&   adrstr1, const CString&    adrstr2)
{
   ADDRESS  address1, address2;
   ADDR_RETCODE   adrRet = ADR_OK;

   adrRet = AdrTextToAddr(adrstr1, address1);
   if (ADR_OK != adrRet)
      return adrRet;
   adrRet = AdrTextToAddr(adrstr2, address2);
   if (ADR_OK != adrRet)
      return adrRet;
      
   adrRet = AdrCheck2Addr(address1, address2);
   return adrRet;
}

ADDR_RETCODE
AdrCheck2Addr(ADDRESS   address1, ADDRESS    address2)
{
   ADDR_RETCODE   adrRet = ADR_OK;
   
   if (SPACE_UNDEFINE != address2.adrSpace) {//address2 define space
      if ( g_nBankNum == 0 ) {
	      if (address1.adrSpace != address2.adrSpace) {
	         adrRet = ADR_COMPERROR;
	         return adrRet;
	      }   
	  }
	  else {
	      if ( address1.adrSpace < SPACE_BANK1 &&            
	      	   address1.adrSpace != address2.adrSpace) {
	         adrRet = ADR_COMPERROR;
	         return adrRet;
	      }                                       
	      else {
	      	 if ( address1.adrSpace > address2.adrSpace ) {
		         adrRet = ADR_COMPERROR;
		         return adrRet;      	
	      	 }	
	      }
	  }    
   }
   else
     address2.adrSpace = address1.adrSpace;  //address2 undefine space
                                             // make address1 and 
                                             // address2 the same space

   if (!AdrCheckAddrRange(address1)) {
      adrRet = ADR_OUTRANGE;
      return adrRet;
   }   
   if (!AdrCheckAddrRange(address2)) {
      adrRet = ADR_OUTRANGE;   
      return adrRet;      
   }
/*      
   if (address1.adrAddress > address2.adrAddress)
      adrRet = ADR_COMPERROR;
   else
      adrRet = ADR_OK;      
*/
	if (address1.adrSpace < SPACE_BANK1) {      
	   if (address1.adrAddress > address2.adrAddress)
	      adrRet = ADR_COMPERROR;
	   else
	      adrRet = ADR_OK;      
	}      
   else {
   	if ( address1.adrSpace < address2.adrSpace ) {
   		adrRet = ADR_OK;      	
   	}
   	else if (address1.adrSpace == address2.adrSpace) {
		   if (address1.adrAddress > address2.adrAddress)
		      adrRet = ADR_COMPERROR;
		   else
		      adrRet = ADR_OK;         	
   	}                           
   	else {
   		adrRet = ADR_COMPERROR;
   	}
   }
   
   return adrRet;
}  // End of AdrCheck2Addr()


/**----------------------------------------------------------------------
 **   AdrIsOk
 **
 **   adrstr      Set to the address text string;
 **
 **   Remark
 **   Call this function to check the address text string.
 **   No converting.
 **
 **   Return value
 **   True if the address text string is correct.
 **----------------------------------------------------------------------*/
BOOL
AdrIsOk(const LPSTR   adrstr)
{
   //ASSERT(NULL != adrstr);
   int isHex = 1;

   C51Address  address(adrstr, isHex);
   BOOL        bIsOk = FALSE;
   ADDRESS     addr;
   
   bIsOk = address.ConvertCheck();
   if (bIsOk) {
      addr.adrSpace = address.GetSpace();
      addr.adrAddress = address.GetAddress();
   }
   else
      return FALSE;
   
   bIsOk = AdrCheckAddrRange(addr);
   
   return bIsOk;
}

BOOL
AdrIsOk(const CString  adrstr)
{
   //ASSERT("" != adrstr);
   int isHex = 1;
   C51Address  address(adrstr, isHex);
   BOOL        bIsOk = FALSE;
   ADDRESS     addr;
   
   bIsOk = address.ConvertCheck();
   if (bIsOk) {
      addr.adrSpace = address.GetSpace();
      addr.adrAddress = address.GetAddress();
   }
   else
      return FALSE;
   
   bIsOk = AdrCheckAddrRange(addr);

   return bIsOk;
}  // End of AdrIsOk()

/**----------------------------------------------------------------------
 **   AdeErrorDeal
 **
 **   Remark
 **   Process the address server's error.
 **   Call this function to display a message box(for general window
 **   process) if the callers don't want to process the error by themself.
 **
 **   Return value
 **   none
 **----------------------------------------------------------------------*/
void
AdrErrorDeal(ADDR_RETCODE  retCode, CString &error)
{
   switch(retCode) {
      case  ADR_OK:              // the address is ok
            //error = "Address is OK!!";
            //::ErrGetErrorText(, strError);
            break;

      case  ADR_FORMATERROR:     // the address format is error
            ::ErrGetErrorText(ER_ADDR_FORMAT, error);
            break;

      case  ADR_INVALIDCHAR:     // the address include invalid char
            ::ErrGetErrorText(ER_ADDR_INVALID, error);
            break;

      case  ADR_OUTRANGE:        // the address out of range
            ::ErrGetErrorText(ER_ADDR_OUTRANGE, error);
            break;

      case  ADR_NOSYMBOL:        // The symbol doesn't exist(Only for conver
                                 // symbol to ADDRESS)
            ::ErrGetErrorText(ER_ADDR_SYMBOL, error);
            break;

      case  ADR_COMPERROR:       // the second address is less than first
            ::ErrGetErrorText(ER_ADDR_COMPARE, error);
            break;

      case  ADR_OVERFLOW:
            ::ErrGetErrorText(ER_ADDR_OVERFLOW, error);
            break;
            
      case  ADR_EMPTY:           // The address text string is empty
            ::ErrGetErrorText(ER_ADDR_EMPTY, error);
            break;   
      case  ADR_NOBANK:                             
      		::ErrGetErrorText(ER_ADDR_NOBANK, error);
      		break;
      case  ADR_BANKERROR:                          
      		::ErrGetErrorText(ER_ADDR_BANKERROR, error);
      		break;		      
      default:
            ::ErrGetErrorText(ER_ADDR_EMPTY, error);
            break;      
   }
}  // End of AdrErrorDeal()

/**--------------------------------------------------------------------------
 **  Name:   AdrSetAddrRange
 **
 **  Description: Call this function to set the six static memner data(max or
 **               min address range). This function is a static function.
 **               Call this function must before all function. As follow
 **                   C51Address::SetAdrRange()
 **
 **  Parameters:
 **     input: none
 **
 **     output:none
 **-------------------------------------------------------------------------*/
 
void
AdrSetAddrRange()
{
   //Call CPU server, get all space address range
   //
   CPUMEMORYRANGE stRange;

   GetMemoryRange(&stRange);  // Get the current cpu memory
   dwpMin = stRange.pMin;     // program min
   dwpMax = stRange.pMax;     // program max
   dwxMin = stRange.xMin;     // data min
   dwxMax = stRange.xMax;     // data max
   dwiMin = stRange.iMin;     // on_chip min
   dwiMax = stRange.iMax;     // on_chip max
   dwrMin = stRange.rMin;     // sfr min
   dwrMax = stRange.rMax;     // sfr max
   dwbMin = stRange.bMin;     // bit min
   dwbMax = stRange.bMax;     // bit max

//   #ifdef _DEBUG
//   dwpMax = 0xffff;
//   dwxMax = 0xffff;
//   dwiMax = 0xff;
//   dwbMax = 0xff;
//   dwrMax = 0xff;
   
//   #endif
}                                      


ADDR_RETCODE
AdrShlCheck2ListAddr(const LPSTR adrstr1, const LPSTR  adrstr2)
{

   ADDRESS  address1, address2;
   ADDR_RETCODE   adrRet = ADR_OK;
 
   adrRet = AdrTextToAddr(adrstr1, address1);
   if (ADR_OK != adrRet) {
      CString error;
 	  AdrErrorDeal(adrRet, error);
 	  char* pszError = new char[error.GetLength()+2];
 	  strcpy(pszError, error);
 	  ShowLine(pszError);
 	  delete []pszError;
      return adrRet;      
   }   
   
   adrRet = AdrTextToAddr(adrstr2, address2);
   if (ADR_OK != adrRet) {
      CString error;
 	  AdrErrorDeal(adrRet, error);
 	  char* pszError = new char[error.GetLength()+2];
 	  strcpy(pszError, error);
 	  ShowLine(pszError);
 	  delete []pszError;
      return adrRet;
   }   


   if ( (address1.adrSpace == SPACE_UNDEFINE) &&
   		(address2.adrSpace == SPACE_UNDEFINE) ) {
	   if (address1.adrAddress > address2.adrAddress) {
	      adrRet = ADR_COMPERROR;                      
	   }   
	   else {  
	      if ( address1.adrAddress > dwpMax ||
	           address2.adrAddress > dwpMax ) {
	         adrRet = ADR_OUTRANGE;  
	      }
	      else {     		
	      	 adrRet = ADR_OK;      
	      }	
	   }         
   }		
   else {
      adrRet = ADR_FORMATERROR;   	   
   }

   if (ADR_OK != adrRet) {
      CString error;
 	  AdrErrorDeal(adrRet, error);
 	  char* pszError = new char[error.GetLength()+2];
 	  strcpy(pszError, error);
 	  ShowLine(pszError);
 	  delete []pszError;  
   }     
   return adrRet;
}



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

