/*************************************************************************
**
**    $Header:   D:/ECB2S/SRC/LOG/MAPDLG.CPP   1.2.1.4   17 Apr 1997 15:55:42   ZJRD  $
**
**    $Log:   D:/ECB2S/SRC/LOG/MAPDLG.CPP  $
** 
**    Rev 1.2.1.4   17 Apr 1997 15:55:42   ZJRD
** No change.
** 
**    Rev 1.2.1.3   16 Apr 1997 10:26:44   ZJRD
** No change.
** 
**    Rev 1.2.1.2   10 Apr 1997 15:37:20   ZJRD
** No change.
** 
**    Rev 1.2.1.1   03 Apr 1997 15:16:50   ZJRD
** No change.
** 
**    Rev 1.2.1.0   28 Mar 1997 10:21:54   ZJRD
** easy pack sld 2.09d
** 
**    Rev 1.1   19 Mar 1997 11:32:02   ZJRD
** Easy Pack SLD 2.09c
** 
**    Rev 1.0   12 Mar 1997 14:47:44   ZJRD
** Initial revision.
** 
**    Rev 1.7.1.0.1.2   09 Dec 1996 10:15:14   ZJRD
** EasyPack/SLD Version 2.0P
** 
**    Rev 1.7.1.0.1.0   11 Nov 1996 12:58:30   ZJRD
** EasyPack/SLD Version 2.01
** 
**    Rev 1.7.1.4   09 Sep 1996 13:15:54   ZJRD
** No change.
** 
**    Rev 1.7.1.3   05 Sep 1996 11:27:28   ZJRD
** EasyPack/SLD Version 1.9e
** 
**    Rev 1.7.1.2   02 Sep 1996 09:54:34   ZJRD
** No change.
** 
**    Rev 1.7.1.1   28 Aug 1996 15:48:46   ZJRD
** EasyPack/SLD Version 1.9b
**************************************************************************/

#include "stdafx.h"
#include "resource.h"
#include "uicom.h"
#include "xview.h"
#include "myedit2.h"
#include "spin.h"
#include "cpucom.h"
#include "abibase.h"
#include "cpuserve.h"

//
// For address server
//
#include "address.h"
#include "addrapi.h"

#include "mapedit.h"
#include "mapbtn.h"
#include "mapdlg.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
                        ****************************/
extern void MemServerSetMap(const unsigned short uStart,
                            const unsigned short uEnd,
                            const unsigned char uchType,
                            const char chMapAttr);
                            
extern BOOL MemServerGetMap(unsigned short& uStart,
                            unsigned short& uEnd,
                            unsigned char& uchType,
                            char& chMapAttr);

extern void SaveConfig(LPCSTR filename, int option);
extern void LoadConfig(LPCSTR filename, int option);
extern int GetMemoryRange(CPUMEMORYRANGE *stRange);
extern STATUS AbiGetCpuId(UINT *nCpuId);

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

                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/
#define     IRW_COLOR         5
#define     IR_COLOR          2
#define     GUARD_COLOR       8
#define     ERW_COLOR         4
#define     ER_COLOR          7
#define     CRW_COLOR         3
#define     CR_COLOR          6

#define     BTN_IRW           10
#define     BTN_IR            11
#define     BTN_GUARD         12
#define     BTN_ERW           13
#define     BTN_ER            14
#define     BTN_CRW           15
#define     BTN_CR            16

#define     BLOCK_LINE        16       // 8
#define     BLOCK_COLON       32       // 8

#define     BLOCK_NUM         512      // 64
#define     BYTE_PER_BLOCK    128      // 1024
   
                       /****************************
                        *                          *
                        *       GLOBAL VARS        *
                        *                          *
                        ****************************/
char  strSelectItem[100];
char  *strPosition;
char  strStartAddress[10];
char  strEndAddress[10];
char  strLength[10];
char  strAttrib[30];
char  strSpace[40];
int   gnAttribIndex = 0;

                       /****************************
                        *                          *
                        *     LOCAL PROTOTYPES     *
                        *                          *
                        ****************************/
BOOL DoMapRestore();             // Restore the map setting from the file
void DoMapSave();                // Save the map setting to the file

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


////////////////////////////////////////////////////////////////////////////
// DoMapSave
//
// Save the map setting to the file map.sav.
// The file is under the execution file's path
// 
// parameter
//    none
//
// return value
//    none
//
////////////////////////////////////////////////////////////////////////////

void DoMapSave()
{
    unsigned short sAddress, eAddress;
    unsigned char space;
    char attribute;
    int count = 0;
    int loop;
    WORD w = 0;
    ADDRESS startAddress, endAddress;
    
    //
    // Do the first get map setting is for getting the map setting count
    //
    // Get Program area map setting
    //
    if (dwpMax != 0) {        // Have code area
		for(loop=1; loop<=5; loop++)
		{
	       if(!g_nBankNum&&loop>1)
	       		break;
	       if(g_nBankNum&&loop==1)
	       		continue;
	       if(g_nBankNum==2&&loop>3)
	       		break;
	       space = loop;
	       if(space>1)
	       		space+=4;
	       startAddress.adrAddress = dwpMin;
	       startAddress.adrSpace = (ADDR_SPACE)space;
	       endAddress.adrAddress = dwpMax;
	       endAddress.adrSpace = (ADDR_SPACE)space;
	       do{
	           sAddress = (unsigned short)startAddress.adrAddress;
	           eAddress = (unsigned short)endAddress.adrAddress;
	           MemServerGetMap(sAddress,
	                           eAddress,
	                           space, 
	                           attribute);
	           endAddress.adrAddress = (ADDR_SIZE)eAddress;                         
	           startAddress.adrAddress = (ADDR_SIZE)sAddress;
	                           
	           startAddress.adrAddress = endAddress.adrAddress + 1;
	           count++;
	       }while (endAddress.adrAddress < dwpMax);
		}
    }
    
    // Get Data area map setting
    if (dwxMax != 0) {        // Have code area
       space = 2;
       startAddress.adrAddress = dwxMin;
       startAddress.adrSpace = (ADDR_SPACE)space;
       endAddress.adrAddress = dwxMax;
       endAddress.adrSpace = (ADDR_SPACE)space;
       
       do{
           sAddress = (unsigned short)startAddress.adrAddress;
           eAddress = (unsigned short)endAddress.adrAddress;
           
           MemServerGetMap(sAddress,
                           eAddress,
                           space, 
                           attribute);
   
           endAddress.adrAddress = (ADDR_SIZE)eAddress;                         
           startAddress.adrAddress = (ADDR_SIZE)sAddress;
       
           startAddress.adrAddress = endAddress.adrAddress + 1;
           count++;
       }while (endAddress.adrAddress < dwxMax);
    }
    
    char exefilename[125];
    
    ::GetModuleFileName(AfxGetInstanceHandle(), exefilename, 125);
    int pp = 0;
    for (pp = strlen(exefilename); pp > 0; pp--) {
      if (exefilename[pp] == '\\')
         break;
   }        
    
    exefilename[pp+1] = '\0';
    strcat(exefilename, "map.sav");
    CFile file(exefilename, CFile::modeCreate|CFile::modeWrite);
    CArchive ar(&file,CArchive::store);
    
    CString flag = "MICROTEK MAP FILE.";
    ar << flag;
    UINT nCurCpuID = 0;
    AbiGetCpuId( &nCurCpuID );
    ar << (BYTE)nCurCpuID;
    w=(WORD)g_nBankNum;
    ar << w;
    w = (WORD)count;
    ar << w;
    
    // Do the second get map setting is for getting the map setting
    //
    // Program area map setting
    //
    if (dwpMax != 0) {        // Have code area
		for(loop=1; loop<=5; loop++)
		{
	       if(!g_nBankNum&&loop>1)
	       		break;
	       if(g_nBankNum&&loop==1)
	       		continue;
	       if(g_nBankNum==2&&loop>3)
	       		break;
	       space = loop;
	       if(space>1)
	       		space+=4;
	       startAddress.adrAddress = dwpMin;
	       startAddress.adrSpace = (ADDR_SPACE)space;
	       endAddress.adrAddress = dwpMax;
	       endAddress.adrSpace = (ADDR_SPACE)space;
	       
	       do{
	           sAddress = (unsigned short)startAddress.adrAddress;
	           eAddress = (unsigned short)endAddress.adrAddress;
	           MemServerGetMap(sAddress,
	                           eAddress,
	                           space, 
	                           attribute);
	           endAddress.adrAddress = (ADDR_SIZE)eAddress;                         
	           startAddress.adrAddress = (ADDR_SIZE)sAddress;
	                           
	           w = (WORD)startAddress.adrAddress;
	           ar << w;
	           w = (WORD)endAddress.adrAddress;
	           ar << w;
	           w = (WORD)space;
	           ar << w;
	           w = (WORD)attribute;
	           ar << w;
	   
	           startAddress.adrAddress = endAddress.adrAddress + 1;
	       }while (endAddress.adrAddress < dwpMax);
		}
    }
                                    
    // Data area map setting
    //                                    
    if (dwxMax != 0) {        // Have data area
       space = 2;
       startAddress.adrAddress = dwxMin;
       startAddress.adrSpace = (ADDR_SPACE)space;
       endAddress.adrAddress = dwxMax;
       endAddress.adrSpace = (ADDR_SPACE)space;
   
       do{
           sAddress = (unsigned short)startAddress.adrAddress;
           eAddress = (unsigned short)endAddress.adrAddress;
           
           MemServerGetMap(sAddress,
                           eAddress,
                           space, 
                           attribute);
   
           endAddress.adrAddress = (ADDR_SIZE)eAddress;                         
           startAddress.adrAddress = (ADDR_SIZE)sAddress;
                           
           w = (WORD)startAddress.adrAddress;
           ar << w;
           w = (WORD)endAddress.adrAddress;
           ar << w;
           w = (WORD)space;
           ar << w;
           w = (WORD)attribute;
           ar << w;
   
           startAddress.adrAddress = endAddress.adrAddress + 1;
       }while (endAddress.adrAddress < dwxMax);
    }
    
    ar.Close();
    file.Close();
}     // End of DoMapSave()


///////////////////////////////////////////////////////////////////////////  
// DoMapRestore
//
// Restore the map setting from the file map.sav.
// The file is under the execution file's path
//
// parameter
//    none
//
// return value
//    none
//
////////////////////////////////////////////////////////////////////////////

BOOL DoMapRestore()
{
    unsigned short startAddress,endAddress;
    unsigned char space;
    char attribute;
    int count;
    int i;
    WORD w;
    CFile file;
    BOOL b;

    char exefilename[125];
    ::GetModuleFileName(AfxGetInstanceHandle(), exefilename, 125);
    int pp = 0;
    for (pp = strlen(exefilename); pp > 0; pp--) {
      if (exefilename[pp] == '\\')
         break;
    }        
    
    exefilename[pp+1] = '\0';
    strcat(exefilename, "map.sav");
    
    b = file.Open(exefilename, CFile::modeRead);
    if (!b) {
        file.Abort();
        /*
        AfxMessageBox("Error Open Map File",
                      MB_OK|MB_ICONHAND|MB_ICONSTOP);
        */
        return FALSE;
    }

    CArchive ar(&file, CArchive::load);
    
    //if ( !ar.IsLoading() )
    //	return FALSE;
    	
    UINT nCurCpuID = 0, nOldCpuID = 0;
    BYTE bTemp = 0;
    AbiGetCpuId( &nCurCpuID );

    CString flag;
    CString oldflag = "MICROTEK MAP FILE.";
    
    ar >> flag;
    if ( flag != oldflag ) {
    	//AfxMessageBox("Map File Format Error",
        //              MB_OK|MB_ICONHAND|MB_ICONSTOP);
		return FALSE;
	}
	                      
    ar >> bTemp;
    nOldCpuID = (UINT)bTemp;
    if ( nCurCpuID != nOldCpuID ) return FALSE;
    ar >> w;
    if(w!=(WORD)g_nBankNum)
    	return FALSE;
    ar >> w;
    count = (int)w;
    
    for(i=1; i<=count; i++) {
        ar >> w;
        startAddress = (unsigned short)w;
        ar >> w;
        endAddress = (unsigned short)w;
        ar >> w;
        space = (unsigned char)w;
        ar >> w;
        attribute = (char)w;
        
        switch( space ) {
            case  1:          // Program
            case  6:
            case  7:
            case  8:
            case  9:
                  if ( dwpMax == 0 && dwpMin == 0 ) {
                     // no this area                        
                  }                  
                  else {
                     if ( startAddress < dwpMin )
                        startAddress = (unsigned short)dwpMin;
                     if ( endAddress > dwpMax )
                        endAddress = (unsigned short)dwpMax;
                     
                     MemServerSetMap(startAddress, 
                                     endAddress, 
                                     space, 
                                     attribute);
                  }                                       
                  break;
                  
            case  2:          // Data
                  if ( dwxMax == 0 && dwxMin == 0 ) {
                     // no this area                        
                  }                  
                  else {
                     if ( startAddress < dwxMin )
                        startAddress = (unsigned short)dwxMin;
                     if ( endAddress > dwxMax )
                        endAddress = (unsigned short)dwxMax;
                     
                     MemServerSetMap(startAddress, 
                                     endAddress, 
                                     space, 
                                     attribute);
                  }                                       
                  break;
        }
           
        // Call memory server
    }

    ar.Close();
    file.Close();

    return TRUE;
}     // End of DoRestoreMap()


/////////////////////////////////////////////////////////////////////////////
// CMapDlg dialog
//
extern COLORREF PaletteIndex[16];

CMapDlg::CMapDlg(CWnd* pParent /*=NULL*/, BOOL bFlag)
   : CDialog(CMapDlg::IDD, pParent)
{
   //{{AFX_DATA_INIT(CMapDlg)
   m_nAreaSelect = 0;
   //}}AFX_DATA_INIT
   m_nArea = 1;
   m_nColorIndex = 9;
   m_bCapture = FALSE;
   //m_bStart = FALSE; 
   //m_bEnd = FALSE;
   m_dwStartAddr = m_dwEndAddr = m_dwCurAddr = 0;   
   m_bFirst = TRUE;
   m_nSelectLast = -1;
   m_nStartBlock = -1;   
   m_nEndBlock = -1;   
   m_nLastBlock = -1;   
   m_nCurBlock = -1;   
   m_bFirstFlag = bFlag;
}

void CMapDlg::DoDataExchange(CDataExchange* pDX)
{
   CDialog::DoDataExchange(pDX);
   //{{AFX_DATA_MAP(CMapDlg)
   DDX_Control(pDX, IDC_MAP_UNDO, m_ctrlUndo);
   DDX_Control(pDX, IDC_MAP_EDIT, m_ctrlMapEdit);
   DDX_Control(pDX, IDC_CURADDR, m_ctrlCurAddr);
   DDX_Control(pDX, IDC_MAP_VIEW, m_ctrlMapView);
   DDX_Control(pDX, IDC_MAP_LIST, m_ctrlListMap);
   DDX_Control(pDX, IDC_STARTADDR, m_ctrlStartAddr);
   DDX_Control(pDX, IDC_ENDADDR, m_ctrlEndAddr);
   //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CMapDlg, CDialog)
   //{{AFX_MSG_MAP(CMapDlg)
   ON_BN_CLICKED(IDC_MAP_RESTORE, OnMapRestore)
   ON_BN_CLICKED(IDC_MAP_SAVE, OnMapSave)
   ON_BN_CLICKED(IDC_MAP_SET, OnMapSet)
   ON_BN_CLICKED(IDC_BTN_CR, OnBtnCr)
   ON_BN_CLICKED(IDC_BTN_CRW, OnBtnCrw)
   ON_BN_CLICKED(IDC_BTN_ER, OnBtnEr)
   ON_BN_CLICKED(IDC_BTN_ERW, OnBtnErw)
   ON_BN_CLICKED(IDC_BTN_G, OnBtnG)
   ON_BN_CLICKED(IDC_BTN_IR, OnBtnIr)
   ON_BN_CLICKED(IDC_BTN_IRW, OnBtnIrw)
   ON_BN_CLICKED(IDC_RDATA, OnRdata)
   ON_BN_CLICKED(IDC_RPROGRAM, OnRprogram)
   ON_WM_PAINT()
   ON_WM_MOUSEMOVE()
   ON_WM_LBUTTONDOWN()
   ON_WM_LBUTTONUP()
   ON_BN_CLICKED(IDC_MAP_EDIT, OnMapEdit)
   ON_LBN_SELCHANGE(IDC_MAP_LIST, OnSelchangeMapList)
   ON_LBN_SETFOCUS(IDC_MAP_LIST, OnSetfocusMapList)
   ON_LBN_KILLFOCUS(IDC_MAP_LIST, OnKillfocusMapList)
   ON_BN_CLICKED(IDC_MAP_UNDO, OnMapUndo)
	ON_BN_CLICKED(IDC_RBANK1, OnRbank1)
	ON_BN_CLICKED(IDC_RBANK2, OnRbank2)
	ON_BN_CLICKED(IDC_RBANK3, OnRbank3)
	ON_BN_CLICKED(IDC_RBANK4, OnRbank4)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CMapDlg message handlers

BOOL CMapDlg::OnInitDialog()
{
   CDialog::OnInitDialog();
   CenterWindow();
   
   BOOL bFind = FALSE;
   bFind = FindMapSave();
   if ( bFind == FALSE ) {
   	  GetDlgItem(IDC_MAP_RESTORE)->EnableWindow(FALSE);
   }
   else {
   	  GetDlgItem(IDC_MAP_RESTORE)->EnableWindow(TRUE);
   }	  
   //CheckRadioButton(IDC_RPROGRAM, IDC_RBANK4, IDC_RPROGRAM);
   if(g_nBankNum==0)
   {
   		GetDlgItem(IDC_RBANK1)->EnableWindow(FALSE);
   		GetDlgItem(IDC_RBANK2)->EnableWindow(FALSE);
   		GetDlgItem(IDC_RBANK3)->EnableWindow(FALSE);
   		GetDlgItem(IDC_RBANK4)->EnableWindow(FALSE);
   		((CButton*)GetDlgItem(IDC_RPROGRAM))->SetCheck(1);
   }
   else if(g_nBankNum==2)
   {
   		((CButton*)GetDlgItem(IDC_RPROGRAM))->SetCheck(0);
   		GetDlgItem(IDC_RBANK3)->EnableWindow(FALSE);
   		GetDlgItem(IDC_RBANK4)->EnableWindow(FALSE);
   		GetDlgItem(IDC_RPROGRAM)->EnableWindow(FALSE);
   		((CButton*)GetDlgItem(IDC_RBANK1))->SetCheck(1);
   }
   else
   	{
   		((CButton*)GetDlgItem(IDC_RPROGRAM))->SetCheck(0);
   		GetDlgItem(IDC_RPROGRAM)->EnableWindow(FALSE);
   		((CButton*)GetDlgItem(IDC_RBANK1))->SetCheck(1);
   	}
   if (dwpMax == 0 && dwpMin == 0) {
      GetDlgItem(IDC_RPROGRAM)->EnableWindow(FALSE);
      GetDlgItem(IDC_RBANK1)->EnableWindow(FALSE);
      GetDlgItem(IDC_RBANK2)->EnableWindow(FALSE);
      GetDlgItem(IDC_RBANK3)->EnableWindow(FALSE);
      GetDlgItem(IDC_RBANK4)->EnableWindow(FALSE);
      ((CButton*)GetDlgItem(IDC_RBANK1))->SetCheck(0);
      ((CButton*)GetDlgItem(IDC_RDATA))->SetCheck(1);
   }
   if (dwxMax == 0 && dwxMin == 0) {
      GetDlgItem(IDC_RDATA)->EnableWindow(FALSE);
      ((CButton*)GetDlgItem(IDC_RDATA))->SetCheck(0);
   }
   
   InitBtn();   
   m_ctrlMapView.GetWindowRect(m_ViewRect);
   ScreenToClient(m_ViewRect);
   
   int left = 0, top = 0, right = 0, bottom = 0;
   CPoint topleft;
   int blockwidth = 11;
   int blockheight= 10;
   int leftmargin = 5;
   int topmargin = 7; 
   
   topleft = m_ViewRect.TopLeft();
   for ( int i = 0; i < BLOCK_LINE; i ++) {
      for ( int j = 0; j < BLOCK_COLON; j ++ ) {
         left = topleft.x + leftmargin + j * blockwidth;
         top = topleft.y + topmargin + i * blockheight;
         right = left + blockwidth;
         bottom = top + blockheight;
         m_block[i*BLOCK_COLON+j].m_block.SetRect(left, top, right, bottom);
         m_block[i*BLOCK_COLON+j].attribute = -1;
      }
   }

   CWnd* ctrl;
   ctrl = GetDlgItem(IDC_BTN_CR);
   ((CButton*)ctrl)->EnableWindow(FALSE);
   ctrl = GetDlgItem(IDC_BTN_CRW);
   ((CButton*)ctrl)->EnableWindow(FALSE);
   
   // TODO: Add extra initialization here
   return TRUE;  // return TRUE  unless you set the focus to a control
}

void CMapDlg::InitBtn()
{
   VERIFY(btnIRW.SubclassDlgItem(IDC_BTN_IRW, this));
   VERIFY(btnIR.SubclassDlgItem(IDC_BTN_IR, this));
   VERIFY(btnGuard.SubclassDlgItem(IDC_BTN_G, this));
   VERIFY(btnERW.SubclassDlgItem(IDC_BTN_ERW, this));
   VERIFY(btnER.SubclassDlgItem(IDC_BTN_ER, this));
   VERIFY(btnCRW.SubclassDlgItem(IDC_BTN_CRW, this));
   VERIFY(btnCR.SubclassDlgItem(IDC_BTN_CR, this));
   
   btnIRW.SetColor(IRW_COLOR);
   btnIRW.SetBtnTitle();
   
   btnIR.SetColor(IR_COLOR);
   btnIR.SetBtnTitle();
   
   btnGuard.SetColor(GUARD_COLOR);
   btnGuard.SetBtnTitle();
   
   btnERW.SetColor(ERW_COLOR);
   btnERW.SetBtnTitle();
   
   btnER.SetColor(ER_COLOR);
   btnER.SetBtnTitle();
   
   btnCRW.SetColor(CRW_COLOR);
   btnCRW.SetBtnTitle();
   
   btnCR.SetColor(CR_COLOR);
   btnCR.SetBtnTitle();
}

void CMapDlg::BtnProcess(int nWhichBtn)
{
   btnIRW.m_bHighlight = FALSE;
   btnIRW.SetState(btnIRW.m_bHighlight);
   btnIR.m_bHighlight = FALSE;
   btnIR.SetState(btnIR.m_bHighlight);
   
   btnGuard.m_bHighlight = FALSE;
   btnGuard.SetState(btnGuard.m_bHighlight);   
   
   btnERW.m_bHighlight = FALSE;
   btnERW.SetState(btnER.m_bHighlight);
   btnER.m_bHighlight = FALSE;
   btnER.SetState(btnER.m_bHighlight);
   
   btnCRW.m_bHighlight = FALSE;
   btnCRW.SetState(btnCRW.m_bHighlight);
   btnCR.m_bHighlight = FALSE;
   btnCR.SetState(btnCR.m_bHighlight);

   switch(nWhichBtn) {
      case  BTN_IRW:                            // IRW
            btnIRW.m_bHighlight = TRUE;
            btnIRW.SetState(btnIRW.m_bHighlight);
            break;
            
      case  BTN_IR:                             // IR
            btnIR.m_bHighlight = TRUE;
            btnIR.SetState(btnIR.m_bHighlight);
            break;
            
      case  BTN_GUARD:                          // Guard
            btnGuard.m_bHighlight = TRUE;
            btnGuard.SetState(btnGuard.m_bHighlight);   
            break;
            
      case  BTN_ERW:                            // ERW
            btnERW.m_bHighlight = TRUE;
            btnERW.SetState(btnERW.m_bHighlight);
            break;
            
      case  BTN_ER:                             // ER
            btnER.m_bHighlight = TRUE;
            btnER.SetState(btnER.m_bHighlight);
            break;
            
      case  BTN_CRW:                            // CRW
            btnCRW.m_bHighlight = TRUE;
            btnCRW.SetState(btnCRW.m_bHighlight);
            break;
            
      case  BTN_CR:                             // CR
            btnCR.m_bHighlight = TRUE;
            btnCR.SetState(btnCR.m_bHighlight);
            break;
   }                  
}

void CMapDlg::DrawMapView()
{
   CDC*   pDC;
   CBrush brush;
   CPen   pen(PS_SOLID, 1, RGB(0, 0, 0));
   int    nColorIndex;
   CPoint lefttop, rightbottom, leftbottom, righttop;
   
   pDC = GetDC();
   for ( int i = 0; i < BLOCK_LINE*BLOCK_COLON; i ++ ) {
      switch(m_block[i].attribute) {
         case 0:
             nColorIndex = IRW_COLOR;
             break;
                            
         case 1:
             nColorIndex = IR_COLOR;
             break;
                            
         case 2:
             nColorIndex = ERW_COLOR;
             break;
                            
         case 3:
             nColorIndex = ER_COLOR;
             break;
                            
         case 4:
             nColorIndex = CRW_COLOR;
             break;
                            
         case 5:
             nColorIndex = CR_COLOR;   
             break;
                            
         case 6:
             nColorIndex = GUARD_COLOR;
             break;
             
         default:
             nColorIndex = 9;    
      }
      
      brush.CreateSolidBrush(PaletteIndex[nColorIndex]);
      DrawBlock(pDC, i, &brush, &pen);
      brush.DeleteObject();
   }
   
   ReleaseDC(pDC);
}

void CMapDlg::InitMapView(DWORD startAddress, DWORD endAddress, int attrib)
{
   int startline = 0, endline = 0, startcolon = 0, endcolon = 0;
      
   startline = (int)(startAddress/0x1000);  // each line is 0~0xFFF
   startcolon = (int)(startAddress-(DWORD)(startline*0x1000))/0x80;
   endline = (int)(endAddress/0x1000);    // each line is 0~0xFFF
   endcolon = (int)(endAddress-(DWORD)(endline*0x1000))/0x80;

   int    nWhich = 0;
   
   for (;;) {
      nWhich = startline*BLOCK_COLON+startcolon;
      m_block[nWhich].attribute = attrib;
      startcolon++;
      if ( (startline == endline) && (startcolon > endcolon) )
         break;
      if ( startcolon > (BLOCK_COLON-1) ) {  
         startcolon = 0;
         startline ++;
      }
      if ( startline > endline ) break;   
   }
}

void CMapDlg::DrawInitMap(int nWhichArea)            // Draw the area map 
{
   switch(m_nArea) {
      case  0:                // Data
            m_dwxMin = 0;     // dwxMin
            m_dwxMax = 0xFFFF;// dwxMax
            break;
            
      case  1:
      case	2:					//bank1
      case	3:					//bank2
      case	4:					//bank3
      case	5:					//bank4
            m_dwpMin = 0;     // dwxMin
            m_dwpMax = 0xFFFF;// dwxMax
            break;            // Program
   }
   
   GetMap(nWhichArea);
   DrawMapView();
}

void CMapDlg::DrawBlockFrame(CDC *pDC, int nWhichBlock, CPen* pen)
{
   CPen* oldPen;
   oldPen = pDC->SelectObject(pen);
   
   CPoint lefttop, rightbottom, leftbottom, righttop;
   
   lefttop = m_block[nWhichBlock].m_block.TopLeft();
   rightbottom = m_block[nWhichBlock].m_block.BottomRight();
   
   leftbottom.x = lefttop.x;
   leftbottom.y = rightbottom.y;
   righttop.x = rightbottom.x;
   righttop.y = lefttop.y;
   
   pDC->MoveTo(lefttop);
   pDC->LineTo(leftbottom);
   
   pDC->MoveTo(lefttop);
   pDC->LineTo(righttop);
   
   pDC->MoveTo(rightbottom);
   pDC->LineTo(righttop);
   
   pDC->MoveTo(rightbottom);
   pDC->LineTo(leftbottom);
   pDC->SelectObject(oldPen);
}

//
// Fill the blocks with the attribute
//
void CMapDlg::DrawAllBlockFrame()
{
   CDC* pDC = GetDC();
   CBrush brush(PaletteIndex[m_nColorIndex]);
   CPen  whitepen(PS_SOLID, 1, RGB(255, 255, 255));
   int nWhichBlock, attrib;

   if ( m_nStartBlock == -1 && m_nEndBlock == -1 ) return;   
   for ( nWhichBlock = m_nStartBlock; 
         nWhichBlock <= m_nEndBlock;
         nWhichBlock ++ ) {
      switch ( m_nColorIndex ) {
         case  IRW_COLOR:
               attrib = 0;
               break;
               
         case  IR_COLOR:
               attrib = 1;
               break;
               
         case  GUARD_COLOR:
               attrib = 6;
               break;
               
         case  ERW_COLOR:
               attrib = 2;
               break;
               
         case  ER_COLOR:
               attrib = 3;
               break;
               
         case  CRW_COLOR:
               attrib = 4;
               break;
               
         case  CR_COLOR:
               attrib = 5;
               break;
      }
      
      m_block[nWhichBlock].attribute = attrib;       
      DrawBlock(pDC, nWhichBlock, &brush, &whitepen);    
   }      
   
   ReleaseDC(pDC);
}

void CMapDlg::DrawBlock(CDC *pDC, int nWhichBlock, CBrush* brush, CPen* pen)
{  
   CRect rect = m_block[nWhichBlock].m_block;
   CPoint x, y;
   x = rect.TopLeft();
   y = rect.BottomRight();
   x.x += 2;
   x.y += 2;
   y.x --;
   y.y --;
   rect.SetRect(x.x, x.y, y.x, y.y);
   pDC->FillRect(rect, brush);      
   
   CPen* oldPen;
   oldPen = pDC->SelectObject(pen);
   
   CPoint lefttop, rightbottom, leftbottom, righttop;
   
   lefttop = m_block[nWhichBlock].m_block.TopLeft();
   rightbottom = m_block[nWhichBlock].m_block.BottomRight();
   
   leftbottom.x = lefttop.x;
   leftbottom.y = rightbottom.y;
   righttop.x = rightbottom.x;
   righttop.y = lefttop.y;
   
   pDC->MoveTo(lefttop);
   pDC->LineTo(leftbottom);
   
   pDC->MoveTo(lefttop);
   pDC->LineTo(righttop);
   
   pDC->MoveTo(rightbottom);
   pDC->LineTo(righttop);
   
   pDC->MoveTo(rightbottom);
   pDC->LineTo(leftbottom);
   pDC->SelectObject(oldPen);
}

void CMapDlg::OnMapRestore()
{
   // TODO: Add your control notification handler code here
   m_bCapture = FALSE;
   
   AfxGetApp()->DoWaitCursor(1);   
   DoMapRestore();
   
   GetMap(m_nArea);        // Repaint the map list box
   DrawMapView();
   m_ctrlMapEdit.EnableWindow(FALSE);
   AfxGetApp()->DoWaitCursor(0);   
   
   //
   // Repaint any window relateed to the memory
   //
   ::RepaintMemory();
   ::RepaintBMemory();
   ::RepaintStack();
   ::RepaintVariable();
}

void CMapDlg::OnMapSave()
{
   // TODO: Add your control notification handler code here
   m_bCapture = FALSE;
   AfxGetApp()->DoWaitCursor(1);   
   DoMapSave();   
   GetDlgItem(IDC_MAP_RESTORE)->EnableWindow(TRUE);
   AfxGetApp()->DoWaitCursor(0);   
}

void CMapDlg::OnMapSet()
{
   // TODO: Add your control notification handler code here
   int nBlock = 0;
   char attribute1 = 0, attribute2 = 0;
   unsigned short startAddress = 0, endAddress = 0, curAddress = 0;
   unsigned char space = 0;                           
   
   m_bCapture = FALSE;
   m_ctrlUndo.EnableWindow(FALSE);
   
   AfxGetApp()->DoWaitCursor(1);   
   switch ( m_nArea ) {
      case  0:             // Data
            for ( nBlock = 0; nBlock < BLOCK_NUM; nBlock ++ ) {
              if ( nBlock == 0 ) {
                  startAddress = (unsigned short)(nBlock*0x80);
              }
              else {    
                 attribute1 = (char)m_block[nBlock].attribute;
                 attribute2 = (char)m_block[nBlock-1].attribute;
                 if ( attribute1 == attribute2 ) {
                    curAddress = (unsigned short)(nBlock*0x80);
                    endAddress = (unsigned short)(curAddress+0x7f);
                    if ( endAddress >= dwxMax ) {
                       space = 2;
                       // Call memory server
                       MemServerSetMap(startAddress, 
                                       endAddress, 
                                       space, 
                                       attribute2);
                    }                   
                 }
                 else {
                    space = 2;
                    // Call memory server
                    curAddress = (unsigned short)(nBlock*0x80);
                    endAddress = (unsigned short)(curAddress+0x7f);
                    MemServerSetMap(startAddress, 
                                    endAddress, 
                                    space, 
                                    attribute2);
                    startAddress = (unsigned short)(nBlock*0x80);
                    if ( nBlock == (BLOCK_NUM - 1) ) {
                        endAddress = (unsigned short)(startAddress + 0x7f);
                        MemServerSetMap(startAddress, 
                                       endAddress, 
                                       space, 
                                       attribute1);
                    }                   
                 }
              }   
              if ( startAddress > dwxMax ) break;
            }  
            GetMap(0);            
            break;
            
      case  1:             // Program   
      case	2:				//bank1
      case  3:
      case  4:
      case  5:				//bank4
            for ( nBlock = 0; nBlock < BLOCK_NUM; nBlock ++ ) {
              if ( nBlock == 0 ) {
                  startAddress = (unsigned short)(nBlock*0x80);
              }
              else {    
                 attribute1 = (char)m_block[nBlock].attribute;
                 attribute2 = (char)m_block[nBlock-1].attribute;
                 if ( attribute1 == attribute2 ) {
                    curAddress = (unsigned short)(nBlock*0x80);
                    endAddress = (unsigned short)(curAddress+0x7f);
                    if ( endAddress >= dwpMax ) {
                       space=m_nArea;
                       if(space>1)
                       		space+=4;
                       // Call memory server
                       MemServerSetMap(startAddress, 
                                       endAddress, 
                                       space, 
                                       attribute2);
                    }                   
                 }
                 else {
                    space = m_nArea;
                    if(space>1)
                    	space+=4;
                    // Call memory server
                    curAddress = (unsigned short)(nBlock*0x80);
                    endAddress = (unsigned short)(curAddress+0x7f);
                    MemServerSetMap(startAddress, 
                                    endAddress, 
                                    space, 
                                    attribute2);
                    startAddress = (unsigned short)(nBlock*0x80);
                    if ( nBlock == (BLOCK_NUM - 1) ) {
                        endAddress = (unsigned short)(startAddress + 0x7f);
                        MemServerSetMap(startAddress, 
                                       endAddress, 
                                       space, 
                                       attribute1);
                    }                   
                 }
              }   
              if ( startAddress > dwpMax ) break;
            }  
            GetMap(m_nArea);            
            break;
   }            
   m_ctrlMapEdit.EnableWindow(FALSE);
   AfxGetApp()->DoWaitCursor(0);   
}

/*
void CMapDlg::OnHelp()
{
   // TODO: Add your control notification handler code here
   m_bCapture = FALSE;
   AfxGetApp()->WinHelp(IDD_MAPDLG);
}
*/

void CMapDlg::OnMapEdit()
{
   // TODO: Add your control notification handler code here
   CMapEdit mapEdit;
   int nCurSel = m_ctrlListMap.GetCurSel();

   m_bCapture = FALSE;
   if ( nCurSel != -1 ) {
      GetListSelect(nCurSel);   
   }   
   else {
      return;
   }
         
   switch ( m_nArea ) {
      case     0:          // Data
               mapEdit.m_strSpaceArea = "Data";
               mapEdit.m_nArea = 2;
               break;
               
      case     1:          // Data
               mapEdit.m_strSpaceArea = "Program";
               mapEdit.m_nArea = 1;
               break;
      case     2:          // bank1
               mapEdit.m_strSpaceArea = "Program Bank0";
               mapEdit.m_nArea = 6;
               break;
      case     3:          // bank1
               mapEdit.m_strSpaceArea = "Program Bank1";
               mapEdit.m_nArea = 7;
               break;
      case     4:          // bank1
               mapEdit.m_strSpaceArea = "Program Bank2";
               mapEdit.m_nArea = 8;
               break;
      case     5:          // bank1
               mapEdit.m_strSpaceArea = "Program Bank3";
               mapEdit.m_nArea = 9;
               break;
   }                  
                  
   mapEdit.m_strStartAddr = strStartAddress;
   mapEdit.m_strEndAddr = strEndAddress;
   switch ( gnAttribIndex ) {
      case     5:
               mapEdit.m_nAttribute = 0;
               break;
               
      case     2:
               mapEdit.m_nAttribute = 1;
               BtnProcess(BTN_IR);
               break;
               
      case     4:
               mapEdit.m_nAttribute = 3;
               break;
               
      case     7:
               mapEdit.m_nAttribute = 4;
               break;
               
      case     3:
               mapEdit.m_nAttribute = 5;
               break;
               
      case     6:
               mapEdit.m_nAttribute = 6;
               break;
               
      case     8:
               mapEdit.m_nAttribute = 2;
               break;
   }
   
   mapEdit.DoModal();
   //if ( mapEdit.m_IsSet ) {
		GetMap(m_nArea);
		DrawMapView();
      m_ctrlMapEdit.EnableWindow(FALSE);
   //}
}

//
// Internal Read Only
//
void CMapDlg::OnBtnIr()
{
   // TODO: Add your control notification handler code here
   m_bCapture = FALSE;
   m_nColorIndex = IR_COLOR;
   BtnProcess(BTN_IR);
   DrawAllBlockFrame();
}

//
// Internal Read/Write
//
void CMapDlg::OnBtnIrw()
{
   // TODO: Add your control notification handler code here
   m_bCapture = FALSE;
   m_nColorIndex = IRW_COLOR;
   BtnProcess(BTN_IRW);
   DrawAllBlockFrame();
}

//
// Guard
//
void CMapDlg::OnBtnG()
{
   // TODO: Add your control notification handler code here
   m_bCapture = FALSE;
   m_nColorIndex = GUARD_COLOR;
   BtnProcess(BTN_GUARD);
   DrawAllBlockFrame();
}

//
// External Read Only
//
void CMapDlg::OnBtnEr()
{
   // TODO: Add your control notification handler code here
   m_bCapture = FALSE;
   m_nColorIndex = ER_COLOR;
   BtnProcess(BTN_ER);
   DrawAllBlockFrame();
}

//
// External Read/Write
//
void CMapDlg::OnBtnErw()
{
   // TODO: Add your control notification handler code here
   m_bCapture = FALSE;
   m_nColorIndex = ERW_COLOR;
   BtnProcess(BTN_ERW);
   DrawAllBlockFrame();
}

//
// Combination Read Only
//
void CMapDlg::OnBtnCr()
{
   // TODO: Add your control notification handler code here
   m_bCapture = FALSE;
   m_nColorIndex = CR_COLOR;
   BtnProcess(BTN_CR);
   DrawAllBlockFrame();
}

//
// Combination Read/Write
//
void CMapDlg::OnBtnCrw()
{
   // TODO: Add your control notification handler code here
   m_bCapture = FALSE;
   m_nColorIndex = CRW_COLOR;
   BtnProcess(BTN_CRW);
   DrawAllBlockFrame();
}

void CMapDlg::OnRdata()
{
   // TODO: Add your control notification handler code here
   m_bCapture = FALSE;
   if ( m_nArea == 0 ) return;
   m_nArea = 0;               // Data
   DrawInitMap(m_nArea);
   CWnd* ctrl;
   ctrl = GetDlgItem(IDC_BTN_CR);
   ((CButton*)ctrl)->EnableWindow(TRUE);
   ctrl = GetDlgItem(IDC_BTN_CRW);
   ((CButton*)ctrl)->EnableWindow(TRUE);
   int sele = m_ctrlListMap.GetCurSel();
   if ( sele == -1 ) m_ctrlMapEdit.EnableWindow(FALSE);
}

void CMapDlg::OnRprogram()
{
   // TODO: Add your control notification handler code here
   m_bCapture = FALSE;
   if ( m_nArea == 1 ) return;
   m_nArea = 1;               // Program
   DrawInitMap(m_nArea);
   CWnd* ctrl;
   ctrl = GetDlgItem(IDC_BTN_CR);
   ((CButton*)ctrl)->EnableWindow(FALSE);
   ctrl = GetDlgItem(IDC_BTN_CRW);
   ((CButton*)ctrl)->EnableWindow(FALSE);
   int sele = m_ctrlListMap.GetCurSel();
   if ( sele == -1 ) m_ctrlMapEdit.EnableWindow(FALSE);
}
   
void CMapDlg::OnRbank1()
{
	// TODO: Add your control notification handler code here
   m_bCapture = FALSE;
   if ( m_nArea == 2 ) return;
   m_nArea = 2;               // Program
   DrawInitMap(m_nArea);
   CWnd* ctrl;
   ctrl = GetDlgItem(IDC_BTN_CR);
   ((CButton*)ctrl)->EnableWindow(FALSE);
   ctrl = GetDlgItem(IDC_BTN_CRW);
   ((CButton*)ctrl)->EnableWindow(FALSE);
   int sele = m_ctrlListMap.GetCurSel();
   if ( sele == -1 ) m_ctrlMapEdit.EnableWindow(FALSE);
}

void CMapDlg::OnRbank2()
{
	// TODO: Add your control notification handler code here
   m_bCapture = FALSE;
   if ( m_nArea == 3 ) return;
   m_nArea = 3;               // Program
   DrawInitMap(m_nArea);
   CWnd* ctrl;
   ctrl = GetDlgItem(IDC_BTN_CR);
   ((CButton*)ctrl)->EnableWindow(FALSE);
   ctrl = GetDlgItem(IDC_BTN_CRW);
   ((CButton*)ctrl)->EnableWindow(FALSE);
   int sele = m_ctrlListMap.GetCurSel();
   if ( sele == -1 ) m_ctrlMapEdit.EnableWindow(FALSE);
}

void CMapDlg::OnRbank3()
{
	// TODO: Add your control notification handler code here
   m_bCapture = FALSE;
   if ( m_nArea == 4 ) return;
   m_nArea = 4;               // Program
   DrawInitMap(m_nArea);
   CWnd* ctrl;
   ctrl = GetDlgItem(IDC_BTN_CR);
   ((CButton*)ctrl)->EnableWindow(FALSE);
   ctrl = GetDlgItem(IDC_BTN_CRW);
   ((CButton*)ctrl)->EnableWindow(FALSE);
   int sele = m_ctrlListMap.GetCurSel();
   if ( sele == -1 ) m_ctrlMapEdit.EnableWindow(FALSE);
}

void CMapDlg::OnRbank4()
{
	// TODO: Add your control notification handler code here
   m_bCapture = FALSE;
   if ( m_nArea == 5 ) return;
   m_nArea = 5;               // Program
   DrawInitMap(m_nArea);
   CWnd* ctrl;
   ctrl = GetDlgItem(IDC_BTN_CR);
   ((CButton*)ctrl)->EnableWindow(FALSE);
   ctrl = GetDlgItem(IDC_BTN_CRW);
   ((CButton*)ctrl)->EnableWindow(FALSE);
   int sele = m_ctrlListMap.GetCurSel();
   if ( sele == -1 ) m_ctrlMapEdit.EnableWindow(FALSE);
}

/**----------------------------------------------------------------------
 **   GetMap
 **
 **   Remark
 **      Call this function to get the current map setting.
 **      Call the map server
 **
 **   Return value
 **      none
 **----------------------------------------------------------------------*/


void CMapDlg::GetMap(int nWhichArea)
{
    DWORD    startAddress, endAddress;
    long length;
    char attribute;
    char *buf;
    char *p;
    CFont font;
    int i;

    buf = new char[100];
    ASSERT(NULL != buf);
    if (NULL == buf) {
       MessageBox("Insufficent memory!", "Alloc memory error",
                  MB_OK|MB_ICONEXCLAMATION);
       return;
    }                  
    
    m_ctrlListMap.ResetContent();
    font.Attach(::GetStockObject(ANSI_FIXED_FONT));
    m_ctrlListMap.SetFont(&font, FALSE);
        
    unsigned short sAddress, eAddress;
    unsigned char space = 0;

    // Get program memory map
    //              
    switch (nWhichArea) {
       case    0:                      // Data
               startAddress = m_dwxMin;
               endAddress   = m_dwxMax;             // Program max memory
              // Add by Daniel Lin on 1996.03.25
              // For the map address range
              //
              if ( startAddress == 0 && endAddress == 0 &&
                   startAddress == endAddress)
                 return;
       
             do{ 
                 sAddress = (unsigned short)startAddress;
                 eAddress = (unsigned short)endAddress;
                 
                 memset(buf, ' ', 100*sizeof(char)); 
                 space = 2;                  
                 MemServerGetMap(sAddress,
                                 eAddress,
                                 space,
                                 attribute);
                 
                 endAddress = eAddress;                         
                 startAddress = sAddress;
                 
                 length = endAddress - startAddress + 1;
                 
                 p = buf;
                 sprintf(p, "0x%X,", startAddress);
                 i = lstrlen(buf);
                 buf[i] = ' ';
         
                 p = buf + 10;
                 sprintf(p, "0x%X,", endAddress);
                 i = lstrlen(buf);
                 buf[i] = ' ';
         
                 p = buf + 20;
                 sprintf(p, "0x%lX,", length);
                 i = lstrlen(buf);
                 buf[i] = ' ';
         
                 p = buf + 30;
                 switch(attribute) {
                     case 0:
                         m_nColorIndex = IRW_COLOR;   
                         lstrcpy(p,"Overlay,");
                         break;
                         
                     case 1:
                         m_nColorIndex = IR_COLOR;   
                         lstrcpy(p,"Overlay Read Only,");
                         break;
                         
                     case 2:
                         m_nColorIndex = ERW_COLOR;   
                         lstrcpy(p,"Target,");
                         break;
                         
                     case 3:
                         m_nColorIndex = ER_COLOR;   
                         lstrcpy(p,"Target Read Only,");
                         break;
                         
                     case 4:
                         m_nColorIndex = CRW_COLOR;   
                         lstrcpy(p,"Combination Read/Write,");
                         break;
                         
                     case 5:
                         m_nColorIndex = CR_COLOR;   
                         lstrcpy(p,"Combination Read Only,");
                         break;
                         
                     case 6:
                         m_nColorIndex = GUARD_COLOR;   
                         lstrcpy(p,"Guard,");
                         break;
                     default:
                         m_nColorIndex = ERW_COLOR;   
                         lstrcpy(p,"Target,");
                         break;
                 }
                 i = lstrlen(buf);
                 buf[i]=' ';
         
                 p=buf + 52;
                 lstrcpy(p, "Data");
                 i = strlen(buf);
                 buf[i] = '\0';
         
                 m_ctrlListMap.AddString(buf);
                 InitMapView(startAddress, endAddress, attribute);
                 startAddress = endAddress + 1;
             }while (endAddress<m_dwxMax);
             break;
             
      case     1:                               // Program
      case	   2:								//bank1
      case	   3:								//bank2
      case	   4:								//bank3
      case	   5:								//bank4
               startAddress = m_dwpMin;
               endAddress   = m_dwpMax;             // Program max memory
              // Add by Daniel Lin on 1996.03.25
              // For the map address range
              //
              if ( startAddress == 0 && endAddress == 0 &&
                   startAddress == endAddress)
                 return;
       
             do{ 
                 sAddress = (unsigned short)startAddress;
                 eAddress = (unsigned short)endAddress;
                 
                 memset(buf, ' ', 100*sizeof(char)); 
                 space = nWhichArea;
                 if(space>1)
                 	space+=4;
                 MemServerGetMap(sAddress,
                                 eAddress,
                                 space,
                                 attribute);
                                 
                 startAddress = sAddress;
                 endAddress = eAddress;                
                 length = endAddress - startAddress + 1;
                 
                 p = buf;
                 sprintf(p, "0x%X,", startAddress);
                 i = lstrlen(buf);
                 buf[i] = ' ';
         
                 p = buf + 10;
                 sprintf(p, "0x%X,", endAddress);                 i = lstrlen(buf);
                 buf[i] = ' ';
         
                 p = buf + 20;
                 sprintf(p, "0x%lX,", length);
                 i = lstrlen(buf);
                 buf[i] = ' ';
         
                 p = buf + 30;
                 switch(attribute) {
                     case 0:
                         lstrcpy(p,"Overlay,");
                         break;
                         
                     case 1:
                         lstrcpy(p,"Overlay Read Only,");
                         break;
                         
                     case 2:
                         lstrcpy(p,"Target,");
                         break;
                         
                     case 3:
                         lstrcpy(p,"Target Read Only,");
                         break;
                         
                     case 4:
                         m_nColorIndex = CRW_COLOR;   
                         lstrcpy(p,"Combination Read/Write,");
                         break;
                         
                     case 5:
                         m_nColorIndex = CR_COLOR;   
                         lstrcpy(p,"Combination Read Only,");
                         break;
                         
                     case 6:
                         lstrcpy(p,"Guard,");
                         break;
                         
                     default:
                         lstrcpy(p,"Overlay,");
                         break;
                 }
                 i = lstrlen(buf);
                 buf[i]=' ';
         
                 p=buf + 52;
                 if(nWhichArea==1)
                 	lstrcpy(p, "Program");
                 else if(nWhichArea==2)
                 	lstrcpy(p, "Bank0");
                 else if(nWhichArea==3)
                 	lstrcpy(p, "Bank1");
                 else if(nWhichArea==4)
                 	lstrcpy(p, "Bank2");
                 else if(nWhichArea==5)
                 	lstrcpy(p, "Bank3");
                 i = strlen(buf);
                 buf[i] = '\0';
         
                 m_ctrlListMap.AddString(buf);
                 InitMapView(startAddress, endAddress, attribute);
                 startAddress = endAddress + 1;
             }while (endAddress<m_dwpMax);
             break;
    }               
    
    if ( buf ) delete []buf;
}

void CMapDlg::OnPaint()
{
   CPaintDC dc(this); // device context for painting
   
   if ( m_bFirst ) {
      switch(m_nArea) {
         case  0:                // Data
               m_dwxMin = dwxMin;
               m_dwxMax = dwxMax;
               break;
               
         case  1:
         case  2:
         case  3:
         case  4:
         case  5:
               m_dwpMin = dwpMin;
               m_dwpMax = dwpMax;
               break;            // Program
      }
      
      GetMap(1);
      
      DrawMapView();
      m_bFirst = FALSE;
   }
   else {
      DrawMapView();
      if ( m_nStartBlock != -1 && m_nEndBlock != -1 ) {
         CPen blackpen(PS_SOLID, 1, RGB(255, 255, 255));
         for ( int nWhichBlock = m_nStartBlock; 
               nWhichBlock <= m_nEndBlock;
               nWhichBlock ++ ) {
            DrawBlockFrame(&dc, nWhichBlock, &blackpen);
         }                  
      }
   }      
      
   // TODO: Add your message handler code here
   // Do not call CDialog::OnPaint() for painting messages
}

int nLastBlock = 0;;

void CMapDlg::OnMouseMove(UINT nFlags, CPoint point)
{
   // TODO: Add your message handler code here and/or call default
   char  curAddr[20];
   BOOL  bInMapView = FALSE, bInBlock = FALSE;
   int   nBlock, nMaxBlock;
   CDC   *pDC = GetDC();
   //CBrush brush(PaletteIndex[9/*m_nColorIndex*/]);
   CPen  whitepen(PS_SOLID, 1, RGB(255, 255, 255)),
         blackpen(PS_SOLID, 1, RGB(0, 0, 0));

   bInMapView = m_ViewRect.PtInRect(point);
   if ( bInMapView ) {
      for ( nBlock = 0; nBlock < BLOCK_NUM; nBlock ++ ) {
         bInBlock = m_block[nBlock].m_block.PtInRect(point);
         if ( bInBlock ) {
            int nAttribute = -1;
            switch ( m_nArea ) {
               case  0:       // Data
                     nMaxBlock = dwxMax / 0x7f;
                     if ( nBlock >= nMaxBlock ) return;
                     break;
                        
               case  1:       // Program
               case  2:			//bank1
               case  3:			//bank2
               case  4:			//bank3
               case  5:			//bank4
                     nMaxBlock = dwpMax / 0x7f;
                     if ( nBlock >= nMaxBlock ) return;
                     break;
            }
            
            m_dwCurAddr = DWORD(nBlock*BYTE_PER_BLOCK);
            wsprintf(curAddr, "0x%X", nBlock*BYTE_PER_BLOCK);
            m_ctrlCurAddr.SetWindowText(curAddr);
            if ( m_bCapture ) {           // Mouse Button is down
               int nWhichBlock;
                  
               m_nCurBlock = nBlock;
               if ( m_nCurBlock > m_nSplitBlock ) {
                  m_nStartBlock = m_nSplitBlock;
                  if ( m_nCurBlock >= m_nLastBlock ) {
                     for ( nWhichBlock = m_nLastBlock; 
                           nWhichBlock <= m_nCurBlock;
                           nWhichBlock ++ ) {
                        DrawBlockFrame(pDC, nWhichBlock, &whitepen);
                     }
                     m_nLastBlock = m_nCurBlock;
                  }
                  else {
                     for ( nWhichBlock = m_nCurBlock; 
                           nWhichBlock <= m_nLastBlock;
                           nWhichBlock ++ ) {
                        DrawBlockFrame(pDC, nWhichBlock, &blackpen);
                     }
                     m_nLastBlock = m_nCurBlock;
                  }
                  m_nEndBlock = m_nCurBlock;
               }
               else {         // m_nCurBlock < m_nSplitBlock
                  m_nEndBlock = m_nSplitBlock;
                  m_nStartBlock = m_nCurBlock;
                  if ( m_nCurBlock > m_nLastBlock ) {
                     for ( nWhichBlock = m_nLastBlock; 
                           nWhichBlock <= m_nCurBlock;
                           nWhichBlock ++ ) {
                        DrawBlockFrame(pDC, nWhichBlock, &blackpen);
                     }
                     m_nLastBlock = m_nCurBlock;   
                  }
                  else {
                     for ( nWhichBlock = m_nCurBlock; 
                           nWhichBlock <= m_nLastBlock;
                           nWhichBlock ++ ) {
                        DrawBlockFrame(pDC, nWhichBlock, &whitepen);
                     }
                     m_nLastBlock = m_nCurBlock;
                  }   
               }
               break;
            }   
         }
      }
   }
   
   ReleaseDC(pDC);      
   CDialog::OnMouseMove(nFlags, point);
}

void CMapDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
   // TODO: Add your message handler code here and/or call default
   int   nBlock;
   BOOL  bInBlock = FALSE;
   char  startAddr[20], curAddr[20];
   int   nWhichBlock;
   int   nMaxBlock;   
      
   CDC   *pDC = GetDC();
   CPen  pen(PS_SOLID, 1, RGB(255, 255, 255));     // white pen
   CPen  blackpen(PS_SOLID, 1, RGB(0, 0, 0));      // black pen
   
   m_bCapture = m_ViewRect.PtInRect(point);
   //m_bStart = TRUE;
   for ( nBlock = 0; nBlock < BLOCK_NUM; nBlock ++ ) {
      bInBlock = m_block[nBlock].m_block.PtInRect(point);
      if ( bInBlock ) {
         switch ( m_nArea ) {
            case  0:       // Data
                  nMaxBlock = dwxMax / 0x7f;
                  if ( nBlock >= nMaxBlock ) return;
                  break;
                     
            case  1:       // Program
            case  2:			//bank1
            case  3:			//bank2
            case  4:			//bank3
            case  5:			//bank4
                  nMaxBlock = dwpMax / 0x7f;
                  if ( nBlock >= nMaxBlock ) return;
                  break;
         }
         
         m_ctrlUndo.EnableWindow(TRUE);
         if ( m_nStartBlock != -1 && m_nEndBlock != -1 ) {
            for ( nWhichBlock = m_nStartBlock; 
                  nWhichBlock <= m_nEndBlock;
                  nWhichBlock ++ ) {
               DrawBlockFrame(pDC, nWhichBlock, &blackpen);
            }                  
         }
         
         m_nStartBlock = nBlock;
         m_nEndBlock = nBlock;
         m_nLastBlock = nBlock;
         m_nCurBlock = nBlock;
         m_nSplitBlock = nBlock;
         
         m_dwStartAddr = DWORD(nBlock*BYTE_PER_BLOCK);
         m_dwStartAddr &= 0x0000FFFF;
         wsprintf(startAddr, "0x%X", nBlock*BYTE_PER_BLOCK);
         m_ctrlStartAddr.SetWindowText(startAddr);
         wsprintf(curAddr, "0x%X", nBlock*BYTE_PER_BLOCK);
         m_ctrlCurAddr.SetWindowText(curAddr);
         DrawBlockFrame(pDC, nBlock, &pen);
         
         break;
      }                  
   }
   
   ReleaseDC(pDC);
   CDialog::OnLButtonDown(nFlags, point);
}

void CMapDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
   // TODO: Add your message handler code here and/or call default
   BOOL  bInBlock = FALSE;
   char  startAddr[20], endAddr[20];
   int   nBlock;
   DWORD dwTemp = 0;
      
   //m_bCapture = m_ViewRect.PtInRect(point);
   if ( m_bCapture ) {
      m_bCapture = FALSE;
      //m_bEnd = TRUE;
      for ( nBlock = 0; nBlock < BLOCK_NUM; nBlock ++ ) {
         bInBlock = m_block[nBlock].m_block.PtInRect(point);
         if ( bInBlock ) {
            m_dwEndAddr = DWORD(nBlock*BYTE_PER_BLOCK);
            m_dwEndAddr &= 0x0000FFFF;
            m_dwStartAddr &= 0x0000FFFF;
            if ( m_dwEndAddr < m_dwStartAddr ) {
               dwTemp = m_dwEndAddr;
               m_dwEndAddr = m_dwStartAddr;
               m_dwStartAddr = dwTemp;
               wsprintf(startAddr, "0x%4X", m_dwStartAddr);
               m_ctrlStartAddr.SetWindowText(startAddr);
               wsprintf(endAddr, "0x%4X", m_dwEndAddr);
               m_ctrlEndAddr.SetWindowText(endAddr);
            }
            else {
               wsprintf(endAddr, "0x%X", nBlock*BYTE_PER_BLOCK);
               m_ctrlEndAddr.SetWindowText(endAddr);
            }               
            break;
         }                  
      }
   }
   
   CDialog::OnLButtonUp(nFlags, point);
}


void CMapDlg::OnMapUndo()
{
   // TODO: Add your control notification handler code here
   AfxGetApp()->DoWaitCursor(1);   
   switch( m_nArea ) {
      case  0:          // Data
            GetMap(0);
            DrawMapView();
            break;
            
      case  1:          // Program
      case  2:			//bank1
      case  3:			//bank2
      case  4:			//bank3
      case  5:			//bank4
            GetMap(m_nArea);
            DrawMapView();
            break;
   }
   AfxGetApp()->DoWaitCursor(0);   
   m_ctrlMapEdit.EnableWindow(FALSE);
   m_ctrlUndo.EnableWindow(FALSE);
   
   m_nStartBlock = -1;   
   m_nEndBlock = -1;   
   m_nLastBlock = -1;   
   m_nCurBlock = -1;   
}

void CMapDlg::OnSelchangeMapList()
{
   // TODO: Add your control notification handler code here
   //CPen  solid_pen(PS_SOLID, 1, RGB(0, 0, 0)), 
   //      dot_pen(PS_SOLID, 1, RGB(255, 255, 255));
   CDC *pDC = GetDC();
            
   //DrawSelectMap(m_nSelectLast, pDC);
   m_nSelectLast = m_ctrlListMap.GetCurSel();   
   DrawSelectMap(m_nSelectLast, pDC);
   ReleaseDC(pDC);
}

void CMapDlg::OnSetfocusMapList()
{
   // TODO: Add your control notification handler code here
   //CPen  dot_pen(PS_DOT, 1, RGB(0, 0, 0));
   CDC *pDC = GetDC();
   UpdateData(TRUE);
   if(((CButton*)GetDlgItem(IDC_RPROGRAM))->GetCheck())
   		m_nAreaSelect=0;
   else if(((CButton*)GetDlgItem(IDC_RDATA))->GetCheck())
   		m_nAreaSelect=1;
   else if(((CButton*)GetDlgItem(IDC_RBANK1))->GetCheck())
   		m_nAreaSelect=2;
   else if(((CButton*)GetDlgItem(IDC_RBANK2))->GetCheck())
   		m_nAreaSelect=3;
   else if(((CButton*)GetDlgItem(IDC_RBANK3))->GetCheck())
   		m_nAreaSelect=4;
   else if(((CButton*)GetDlgItem(IDC_RBANK4))->GetCheck())
   		m_nAreaSelect=5;
   else
   		ASSERT(0);
   m_nSelectLast = m_ctrlListMap.GetCurSel();   
   DrawSelectMap(m_nSelectLast, pDC);
   ReleaseDC(pDC);
   
   m_ctrlMapEdit.EnableWindow(TRUE);
}

void CMapDlg::OnKillfocusMapList()
{
   // TODO: Add your control notification handler code here
   //CPen  solid_pen(PS_SOLID, 1, RGB(0, 0, 0));
   CDC *pDC = GetDC();
   DrawSelectMap(m_nSelectLast, pDC);
   ReleaseDC(pDC);
}

BOOL CMapDlg::GetListSelect(int nSelectLast)
{
   if ( nSelectLast == -1 ) return FALSE;
   memset(strSelectItem, 0, 100);
   memset(strStartAddress, 0, 10);   
   memset(strEndAddress, 0, 10);   
   memset(strLength, 0, 10);   
   memset(strAttrib, 0, 30);   
   memset(strSpace, 0, 40);      
   
   m_ctrlListMap.GetText(nSelectLast, strSelectItem);
   strPosition = strSelectItem;
   strncpy(strStartAddress, strPosition, 10);
   strncpy(strEndAddress, strPosition+10, 10);
   strncpy(strLength, strPosition+20, 10);
   strncpy(strAttrib, strPosition+30, 22);
   strncpy(strSpace, strPosition+55, 40);   
   
   int iCount;   
   for (iCount = 10; iCount > 0; iCount--) {
      if (',' == strStartAddress[iCount]) {
         strStartAddress[iCount] = '\0';
         break;
      }
   }
   for (iCount = 10; iCount > 0; iCount--) {
      if (',' == strEndAddress[iCount]) {
         strEndAddress[iCount] = '\0';
         break;
      }
   }
   for (iCount = 10; iCount > 0; iCount--) {
      if (',' == strLength[iCount]) {
         strLength[iCount] = '\0';
         break;
      }
   }
   for (iCount = 22; iCount > 0; iCount--) {
      if (',' == strAttrib[iCount]) {
         strAttrib[iCount] = '\0';
         break;
      }
   }
   for (iCount = 40; iCount > 0; iCount--) {
      if (',' == strSpace[iCount]) {
         strSpace[iCount] = '\0';
         break;
      }
   }
   
   if (0 == strcmp(strAttrib, "Overlay")) {
      gnAttribIndex = 5;
      goto SETSEL;
   }
   if (0 == strcmp(strAttrib, "Overlay Read Only")) {
      gnAttribIndex = 2;
      goto SETSEL;
   }
   if (0 == strcmp(strAttrib, "Guard")) {
      gnAttribIndex = 8;
      goto SETSEL;
   }           
   if (0 == strcmp(strAttrib, "Target")) {
      gnAttribIndex = 4;
      goto SETSEL;
   }           
   if (0 == strcmp(strAttrib, "Target Read Only")) {
      gnAttribIndex = 7;
      goto SETSEL;
   }           
   if (0 == strcmp(strAttrib, "Combination Read/Write")) {
      gnAttribIndex = 3;
      goto SETSEL;
   }           
   if (0 == strcmp(strAttrib, "Combination Read Only")) {
      gnAttribIndex = 6;
      goto SETSEL;
   }
   
SETSEL:  
   return TRUE;

}

void CMapDlg::DrawSelectMap(int nSelectLast, CDC* pDC)
{
   ADDRESS nStartAddr, nEndAddr;
   //CBrush brush;
   CPen blackpen(PS_SOLID, 1, RGB(0, 0, 0));
   CPen whitepen(PS_SOLID, 1, RGB(255, 255, 255));
   
   int nWhichBlock;
   if ( m_nStartBlock != -1 && m_nEndBlock != -1 ) {
      for ( nWhichBlock = m_nStartBlock; 
            nWhichBlock <= m_nEndBlock;
            nWhichBlock ++ ) {
         DrawBlockFrame(pDC, nWhichBlock, &blackpen);
      }                  
   }

   if ( FALSE == GetListSelect(nSelectLast) ) return;      

   switch ( gnAttribIndex ) {          // Color Index
      case     5:
               m_nColorIndex = IRW_COLOR;
               BtnProcess(BTN_IRW);
               break;
               
      case     2:
               m_nColorIndex = IR_COLOR;
               BtnProcess(BTN_IR);
               break;
               
      case     4:
               m_nColorIndex = ERW_COLOR;
               BtnProcess(BTN_ERW);
               break;
               
      case     7:
               m_nColorIndex = ER_COLOR;
               BtnProcess(BTN_ER);
               break;
               
      case     3:
               m_nColorIndex = CRW_COLOR;
               BtnProcess(BTN_CRW);
               break;
               
      case     6:
               m_nColorIndex = CR_COLOR;
               BtnProcess(BTN_CR);
               break;
               
      case     8:
               m_nColorIndex = GUARD_COLOR;
               BtnProcess(BTN_GUARD);
               break;
   }
         
   AdrTextToAddr(strStartAddress, nStartAddr);
   AdrTextToAddr(strEndAddress, nEndAddr);
   
   m_ctrlStartAddr.SetWindowText(strStartAddress);
   m_ctrlEndAddr.SetWindowText(strEndAddress);
   
   m_nStartBlock = int(nStartAddr.adrAddress/0x80);
   m_nEndBlock = int(nEndAddr.adrAddress/0x80);
   
   if ( m_nStartBlock != -1 && m_nEndBlock != -1 ) {
      for ( nWhichBlock = m_nStartBlock; 
            nWhichBlock <= m_nEndBlock; 
            nWhichBlock ++ ) {
         DrawBlockFrame(pDC, nWhichBlock, &whitepen);
      }   
   }      
}

BOOL CMapDlg::FindMapSave()
{
    char exefilename[125];
    ::GetModuleFileName(AfxGetInstanceHandle(), exefilename, 125);
    int pp = 0;
    for (pp = strlen(exefilename); pp > 0; pp--) {
      if (exefilename[pp] == '\\')
         break;
    }        
    
    exefilename[pp+1] = '\0';
    strcat(exefilename, "map.sav");
    
    BOOL b;
    CFile file;
    b = file.Open(exefilename, CFile::modeRead);
    if (!b) {
        file.Abort();
        return FALSE;
    }
    
    file.Close();
    return TRUE;
}

/////////////////////////////(EOF of MAPDLG.CPP)/////////////////////////////
