
/***************************************************************************
**
**    $Header:   D:/ECB2S/SRC/LOG/NWMEM.CPP   1.2.1.4   17 Apr 1997 15:57:28   ZJRD  $
**
**    $Log:   D:/ECB2S/SRC/LOG/NWMEM.CPP  $
** 
**    Rev 1.2.1.4   17 Apr 1997 15:57:28   ZJRD
** No change.
** 
**    Rev 1.2.1.3   16 Apr 1997 10:29:00   ZJRD
** No change.
** 
**    Rev 1.2.1.2   10 Apr 1997 15:39:22   ZJRD
** No change.
** 
**    Rev 1.2.1.1   03 Apr 1997 15:18:24   ZJRD
** 2.09E
** 
**    Rev 1.2.1.0   28 Mar 1997 10:23:18   ZJRD
** easy pack sld 2.09d
** 
**    Rev 1.1   19 Mar 1997 11:33:20   ZJRD
** No change.
** 
**    Rev 1.0   12 Mar 1997 14:48:38   ZJRD
** Initial revision.
** 
**    Rev 1.7.1.0.1.2   09 Dec 1996 10:17:36   ZJRD
** EasyPack/SLD Version 2.0P
** 
**    Rev 1.7.1.0.1.0   11 Nov 1996 13:00:50   ZJRD
** EasyPack/SLD Version 2.01
** 
**    Rev 1.7.1.4   09 Sep 1996 13:22:02   ZJRD
** No change.
** 
**    Rev 1.7.1.3   05 Sep 1996 11:33:28   ZJRD
** No change.
** 
**    Rev 1.7.1.2   02 Sep 1996 10:00:32   ZJRD
** No change.
** 
**    Rev 1.7.1.1   28 Aug 1996 15:43:52   ZJRD
** No change.
** 
**    Rev 1.7.1.0   12 Aug 1996 10:49:14   ZJRD
** EasyPack/SLD Version 1.98
** 
**    Rev 1.6.1.0   19 Jul 1996 09:53:56   ZJRD
** EasyPack/SLD Version 1.20b
** 
**    Rev 1.8   20 Jun 1996 09:27:32   ZJRD
** EasyPack/SLD Version 1.20a
** 
**    Rev 1.6   10 Jun 1996 10:22:10   ZJRD
** EasyPack/SLD Version 1.20
** 
**    Rev 1.5   05 Jun 1996 14:51:28   ZJRD
** EasyPack/SLD Version 1.96
** 
**    Rev 1.4   29 May 1996 09:32:46   ZJRD
** EasyPack/SLD Version 1.95
** 
**    Rev 1.3   16 May 1996 09:04:54   ZJRD
** No change.
** 
**    Rev 1.2   10 May 1996 09:13:46   ZJRD
** No change.
** 
**    Rev 1.1   02 May 1996 10:24:18   ZJRD
** EasyPack/SLD Version 1.92
** 
**    Rev 1.31   18 Apr 1996 12:53:34   Shirley
** EasyPack/SLD Version 1.91
** 
**    Rev 1.30   12 Apr 1996 10:40:24   Shirley
** EasyPack/SLD Version 1.90
** 
**    Rev 1.28   15 Feb 1996 08:56:32   Shirley
** No change.
** 
**    Rev 1.27   12 Feb 1996 14:07:52   Shirley
** No change.
** 
**    Rev 1.26   06 Feb 1996 15:34:20   Shirley
** No change.
** 
**    Rev 1.25   06 Feb 1996 13:48:38   Shirley
** EasyPack/SLD Version 0.36
** 
**    Rev 1.24   01 Feb 1996 10:13:00   Shirley
** EasyPack/SLD Version 0.35b
** 
**    Rev 1.23   26 Jan 1996 09:17:14   Shirley
** No change.
** 
**    Rev 1.22   25 Jan 1996 13:17:10   Shirley
** No change.
** 
**    Rev 1.21   24 Jan 1996 10:38:12   Shirley
** EasyPack/SLD Version 0.34d
** 
**    Rev 1.20   23 Jan 1996 11:23:24   Shirley
** EasypPack/SLD Version 0.34c
** 
**    Rev 1.19   18 Jan 1996 10:12:52   Shirley
** No change.
** 
**    Rev 1.18   15 Jan 1996 16:10:20   Shirley
** No change.
** 
**    Rev 1.17   04 Jan 1996 11:09:36   Shirley
** EasyPack/SLD Version 0.34
** 
**    Rev 1.16   30 Nov 1995 09:13:00   Shirley
** EasyPack/SLD Version 0.33
** 
**    Rev 1.15   28 Nov 1995 15:35:20   Shirley
** No change.
** 
**    Rev 1.14   21 Nov 1995 11:24:32   Shirley
** No change.
** 
**    Rev 1.13   13 Nov 1995 09:25:26   Shirley
** No change.
** 
**    Rev 1.12   12 Nov 1995 11:28:22   Shirley
** EasyPack/SLD Version 0.24
**
**    Rev 1.11   08 Nov 1995 16:29:10   Shirley
** No change.
**
**    Rev 1.10   08 Nov 1995 12:39:40   Shirley
** EasyPack/SLD Version 0.22
**
**    Rev 1.4   13 Oct 1995 13:22:52   Shirley
** EasyPack/SLD Version 0.1d
**
**    Rev 1.3   29 Sep 1995 09:49:50   Shirley
** No change.
**
**    Rev 1.2   20 Sep 1995 10:52:52   Shirley
** No change.
**
**    Rev 1.1   15 Sep 1995 09:48:34   Shirley
** EasyPack/SLDV0.1a
**
**    Rev 1.0   07 Sep 1995 09:53:50   Shirley
** Initial revision.
**
****************************************************************************/

/////////////////////////////////////////////////////////////////////////////
//
//  File name:  NWMEM.CPP
//
//  Description:The implement file for the class: CMemoryWindow
//
//  Author:     Lane Li & Daniel Lin
//
//
//  Modification:
//		8. 12/11/1996, for ver.2.1: change window display interface,
//				 add 8 bytes one line mode.		by <<<Chris>>>.
//      7. 03/12/1996--03/26/1996   1.0 Version    Daniel Lin
//              modify function
//               OnPaint()
//               OnSize()
//               OnKeyDown()
//               GetMemory()
//               OnVScroll()
//               OnHScroll()
//               Left()
//               Right()
//               Tab()
//               Tab1()
//               Home()
//               End()
//               OnEditGoto()
//
//
//      6. 1/29/96, 0.35 version       Daniel Lin
//              modified function   GetMemory() 
//
//      5. 10/31/95, 0.1h version               Daniel Lin
//              modified function   ShowAddress()
//              modified function   Up()
//              modified function   Down()
//              modified function   OnKeyDown()
//
//      4. 10/30/95, 0.1h version               Daniel Lin
//              modified function   ShowAddress()
//              modified function   NewMemoryOpenWindow()
//              modified function   GetMemory();
//
//      3. 10/20/95, 0.1d version       Daniel Lin
//              modified function   OnMDIActivate()
//
//      2. 10/19/95, 0.1d version       Daniel Lin
//              modified function   GetMemory();
//              modified function   ShowAddress();
//              modified function   OnKeyDown();
//              modified function   OnRButtonDown()
//
//
//  Modification:
//
//      1. 09/10/95, Initial version
//
//
//  Copyright (C) 1995 Microtek International. All rights reserved.
//
/////////////////////////////////////////////////////////////////////////////

//
// nwmem.cpp : implementation file
//

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#include "stdafx.h"
#include "resource.h"

#include "uicom.h"

#include "zqueue.h"
#include "srccom.h"

#include "xview.h"
#include "nwmem.h"
#include "ctype.h"
#include "errno.h"
#include "myedit2.h"
#include "spin.h"
#include "mapbtn.h"
#include "mapdlg.h"
#include "tabdll11.h"
#include "tabvbmfc.h"
#include "mempage.h"          // Add by Daniel
#include "memdlg.h"
#include "memgtdlg.h"
#include "dsmgtdlg.h"
#include "dad.h"
#include "dsmedit1.h"
#include "dsmedit2.h"
#include "memschdg.h"
#include "cpucom.h"
#include "abibase.h"
#include "cpuserve.h"

#include "address.h"
#include "addrapi.h"
#include "btnbar.h"
#include "mainfrm.h"
#include "colors.h"

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

                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *    EXTERNAL FUNCTION     *
                        *                          *
                        ****************************/
extern long MemServerDump(BYTE*,long,long,int);
extern int MemServerFill(long,BYTE,int);
extern int GetDsm (int, long, int, DADMEMSTRU*, int);
extern BOOL MemServerSearch(ADDRESS Start, ADDRESS End, char* pszPattern, 
		int nInsensitive,ADDRESS& RetAddr);
extern int GetMemoryRange(CPUMEMORYRANGE *stRange);

/*
    Output : uchStatus = the current cpu status
             STATUS_HALT  == 0
             STATUS_GO    == 1
             STATUS_GORUN == 2
    returN : TRUE ==> GET OK
             FALSE ==> GET FAIL
*/
extern BOOL GetCpuStatus(unsigned char & uchStatus);

                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/

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

                       /****************************
                        *                          *
                        *       GLOBAL VARS        *
                        *                          *
                        ****************************/
long linLastStartAddr = 0;
unsigned char   linLastCheck = 1;

//record start address and space of memory, window, next time memory
//window opened from this addr.
static DWORD sdw_Mem1StartAddr = 0;
static DWORD sdw_Mem2StartAddr = 0;
static DWORD sdw_Mem3StartAddr = 0;

//1: program memory; 2: data memory; 3: on chip memory
static BYTE sb_Mem1Space = 1;
static BYTE sb_Mem2Space = 1;
static BYTE sb_Mem3Space = 1;

//record view in byte(1), word(2) or dword(3) in memory window.
static BYTE sb_Mem1ViewMode1 = 1;
static BYTE sb_Mem2ViewMode1 = 1;
static BYTE sb_Mem3ViewMode1 = 1;

//record view in hex(3), unsigned decimal(2), signed decimal(1) or
//instruction(4) in memory window.
static BYTE sb_Mem1ViewMode2 = 3;
static BYTE sb_Mem2ViewMode2 = 3;
static BYTE sb_Mem3ViewMode2 = 3;

static BOOL sb_Mem1ShowAscii = TRUE;
static BOOL sb_Mem2ShowAscii = TRUE;
static BOOL sb_Mem3ShowAscii = TRUE;

static int  sn_Mem1LineGroup = 1;
static int  sn_Mem2LineGroup = 1;
static int  sn_Mem3LineGroup = 1;

//record user input address in goto dialog.
static BYTE sb_GotoSpace1 = 0xff;
static DWORD sdw_GotoAddr1 = 0;

                       /****************************
                        *                          *
                        *   CLASS STATIC VARIBLE   *
                        *                          *
                        ****************************/
CMenu NEAR CMemoryWindow::m_menu;

char CMemoryWindow::m_searchStr[200] = "";

                       /****************************
                        *                          *
                        *      EXECUTABLE CODE     *
                        *                          *
                        ****************************/
                        
////////////////////////////////////////////////////////////////////////
// Minimize all memory window include the three memory window and the 
//  bit memory window
//       Only for when the CPU at GO status, the memory window can not
//       do anything
//                        
void MinAllMemWnd(void)
{   
/*
    if(isMemOn[0]) pMemWnd[0]->ShowWindow(SW_SHOWMINIMIZED);
    if(isMemOn[1]) pMemWnd[1]->ShowWindow(SW_SHOWMINIMIZED);
    if(isMemOn[2]) pMemWnd[2]->ShowWindow(SW_SHOWMINIMIZED);
    if(isBMemOn) pBMemWnd->ShowWindow(SW_SHOWMINIMIZED);
*/    
}

//////////////////////////////////////////////////////////////////////////
// Open the memory window
//    Called by Mainframe
//                        
void NewMemoryOpenWindow(CMDIFrameWnd *pParent,int no)
{
	if (isMemOn[no])
		return;

	pMemWnd[no] = new CMemoryWindow(BYTE(no));
	if(!((CMemoryWindow *)pMemWnd[no])->Create("Memory",
			WS_CHILD|WS_VISIBLE|WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL,
			CFrameWnd::rectDefault, pParent))
		ASSERT(0);
	else
		isMemOn[no]=TRUE;
}

long MyMemServerDump(BYTE* pbDump, long lAddr, long lSize, int nType)
{
long	loop=lSize/0x100;
long	more=lSize%0x100;
BYTE*	pCur=pbDump;
long	CurAddr=lAddr, ret=0;

	for(long i=0; i<loop; i++)
	{
		ret+=MemServerDump(pCur, CurAddr, 0x100, nType);
		pCur+=0x100;
		CurAddr+=0x100;
	}
	if(more)
		ret+=MemServerDump(pCur, CurAddr, more, nType);
	return ret;
}

/////////////////////////////////////////////////////////////////////////////
// CMemoryWindow
//
//
IMPLEMENT_DYNCREATE(CMemoryWindow, CMDIChildWnd)

CMemoryWindow::CMemoryWindow(BYTE no)
{
CPUMEMORYRANGE stRange;

	ASSERT(no>=0&&no<=2);
	m_bWndNo=no;
	switch (no)
	{
		case 0:
			m_dwStartAddress = sdw_Mem1StartAddr;
			m_nSpaceType = sb_Mem1Space;
			m_bViewMode1 = sb_Mem1ViewMode1;
			m_bViewMode2 = sb_Mem1ViewMode2;
			m_bShowAscii = sb_Mem1ShowAscii;
			m_nLineGroup = sn_Mem1LineGroup;
			break;
		case 1:
			m_dwStartAddress = sdw_Mem2StartAddr;
			m_nSpaceType = sb_Mem2Space;
			m_bViewMode1 = sb_Mem2ViewMode1;
			m_bViewMode2 = sb_Mem2ViewMode2;
			m_bShowAscii = sb_Mem2ShowAscii;
			m_nLineGroup = sn_Mem2LineGroup;
			break;
		case 2:
			m_dwStartAddress = sdw_Mem3StartAddr;
			m_nSpaceType = sb_Mem3Space;
			m_bViewMode1 = sb_Mem3ViewMode1;
			m_bViewMode2 = sb_Mem3ViewMode2;
			m_bShowAscii = sb_Mem3ShowAscii;
			m_nLineGroup = sn_Mem3LineGroup;
			break;
		default:
			ASSERT(0);
			break;
	}

	GetMemoryRange( &stRange );         // Get the current cpu memory
	pMin = stRange.pMin;
	pMax = stRange.pMax;
	xMin = stRange.xMin;
	xMax = stRange.xMax;
	iMin = stRange.iMin;
	iMax = stRange.iMax;
	SetRegionEnd();

	m_nIDHelp = IDR_MEMORY;

	m_nLines = 15;             // modify by Daniel Lin on 1996.7.3

	m_wMemBufferLen=1024;
	m_pMemBuffer = new BYTE[m_wMemBufferLen];
	m_dwBufStartAddr=0xffff;
	m_dwBufEndAddr=0;

	m_wDSMBufferLen=128;
	m_dsm= new struct dsm[m_wDSMBufferLen];

	m_bHScrollOn=TRUE;
	m_nPosX = 0;

	m_wCaretPosX1 = 0;
	m_wCaretPosX2 = 0;
	m_wCaretPosY = 0;
	m_nCaretArea = 1;

	m_nCursor = 0;

	m_lpszValue = new char[20];
	ASSERT(m_lpszValue!=NULL);
}

CMemoryWindow::~CMemoryWindow()
{
	isMemOn[m_bWndNo] = FALSE;
	pMemWnd[m_bWndNo] = NULL;

	if (m_pMemBuffer!=NULL)
		delete []m_pMemBuffer;
	if(m_dsm)
		delete []m_dsm;
	if(m_lpszValue)
		delete []m_lpszValue;

	switch(m_bWndNo)
	{
		case  0:
			sdw_Mem1StartAddr = m_dwStartAddress;
			sb_Mem1Space = m_nSpaceType;
			sb_Mem1ViewMode1=m_bViewMode1;
			sb_Mem1ViewMode2=m_bViewMode2;
			sb_Mem1ShowAscii=m_bShowAscii;
			sn_Mem1LineGroup=m_nLineGroup;
			break;
		case  1:
			sdw_Mem2StartAddr = m_dwStartAddress;
			sb_Mem2Space = m_nSpaceType;
			sb_Mem2ViewMode1=m_bViewMode1;
			sb_Mem2ViewMode2=m_bViewMode2;
			sb_Mem2ShowAscii=m_bShowAscii;
			sn_Mem2LineGroup=m_nLineGroup;
			break;
		case  2:
			sdw_Mem3StartAddr = m_dwStartAddress;
			sb_Mem3Space = m_nSpaceType;
			sb_Mem3ViewMode1=m_bViewMode1;
			sb_Mem3ViewMode2=m_bViewMode2;
			sb_Mem3ShowAscii=m_bShowAscii;
			sn_Mem3LineGroup=m_nLineGroup;
			break;
		default:
			ASSERT(0);
	}
}

BOOL CMemoryWindow::Create(LPCSTR szTitle, LONG style,
                        const RECT& rect, CMDIFrameWnd * pParent)
{
HBRUSH	hBackGround;

	hBackGround=CreateSolidBrush(PALETTEINDEX(COLOR_WHITE));

	// Setup the shared m_menu
	if(m_menu.m_hMenu == NULL)  m_menu.LoadMenu(IDR_MEMORY);
	m_hMenuShared = m_menu.m_hMenu;
    
	const char * pszMemoryClass =
		AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,NULL,
							hBackGround,	//System will delete this brush when class is freed.
							AfxGetApp()->LoadIcon(IDR_MEMORY));
	if (!(CMDIChildWnd::Create(pszMemoryClass, szTitle,
							style, rect, pParent)))
		return FALSE;                         
	else
		return TRUE;      
}                         

void CMemoryWindow::ShowStatusGo(void)
{
	CString str = "Running. Halt CPU first.";
	((CMainFrame*)((CXviewApp *)AfxGetApp()->m_pMainWnd))
		->m_wndStatusBar.UpdateStatusBar(0, str);
}

void CMemoryWindow::SetWindowTitle(long addr)
{
char title[40];

	switch (m_nSpaceType)
	{
		case 1:
			switch(m_bWndNo)
			{
				case 0:
					wsprintf(title, "1:Program Memory");
					break;
				case 1:
					wsprintf(title, "2:Program Memory");
					break;
				case 2:
					wsprintf(title, "3:Program Memory");
					break;
				default:
					ASSERT(0);
					//wsprintf(title, "Program Memory");
					break;
			}
			break;
		case 2:
			switch(m_bWndNo)
			{
				case 0:
					wsprintf(title, "1:Data Memory");
					break;
				case 1:
					wsprintf(title, "2:Data Memory");
					break;
				case 2:
					wsprintf(title, "3:Data Memory");
					break;
				default:
					ASSERT(0);
					//wsprintf(title, "Data Memory");
					break;
			}
			break;
		case 3:
			switch(m_bWndNo)
			{
				case 0:
					wsprintf(title, "1:On_Chip Data Memory");
					break;
				case 1:
					wsprintf(title, "2:On_Chip Data Memory");
					break;
				case 2:
					wsprintf(title, "3:On_Chip Data Memory");
					break;
				default:
					ASSERT(0);
					//wsprintf(title, "On_Chip Data Memory");
					break;
			}
			break;
		case 6:
			switch(m_bWndNo)
			{
				case 0:
					wsprintf(title, "1:Program Bank0 Memory");
					break;
				case 1:
					wsprintf(title, "2:Program Bank0 Memory");
					break;
				case 2:
					wsprintf(title, "3:Program Bank0 Memory");
					break;
				default:
					ASSERT(0);
					//wsprintf(title, "Program Memory");
					break;
			}
			break;
		case 7:
			switch(m_bWndNo)
			{
				case 0:
					wsprintf(title, "1:Program Bank1 Memory");
					break;
				case 1:
					wsprintf(title, "2:Program Bank1 Memory");
					break;
				case 2:
					wsprintf(title, "3:Program Bank1 Memory");
					break;
				default:
					ASSERT(0);
					//wsprintf(title, "Program Memory");
					break;
			}
			break;
		case 8:
			switch(m_bWndNo)
			{
				case 0:
					wsprintf(title, "1:Program Bank2 Memory");
					break;
				case 1:
					wsprintf(title, "2:Program Bank2 Memory");
					break;
				case 2:
					wsprintf(title, "3:Program Bank2 Memory");
					break;
				default:
					ASSERT(0);
					//wsprintf(title, "Program Memory");
					break;
			}
			break;
		case 9:
			switch(m_bWndNo)
			{
				case 0:
					wsprintf(title, "1:Program Bank3 Memory");
					break;
				case 1:
					wsprintf(title, "2:Program Bank3 Memory");
					break;
				case 2:
					wsprintf(title, "3:Program Bank3 Memory");
					break;
				default:
					ASSERT(0);
					//wsprintf(title, "Program Memory");
					break;
			}
			break;
		default:
			ASSERT(0);
//			switch(m_bWndNo)
//			{
//				case 0:
//					wsprintf(title, "1:Data Memory");
//					break;
//				case 1:
//					wsprintf(title, "2:Data Memory");
//					break;
//				case 2:
//					wsprintf(title, "3:Data Memory");
//					break;
//				default:
//					ASSERT(0);
//					//wsprintf(title, "Data Memory");
//					break;
//			}
			break;
	}
	if(addr!=-1)
		wsprintf(&title[strlen(title)], " : %04X", addr);
	SetWindowText(title);
}

void CMemoryWindow::FillText(LPCSTR lpszText,UINT nCount,
							 RECT rect,CDC* dc, BOOL isGrey)
{                         
SIZE size;
COLORREF oldColor;
CBrush greyBrush(PALETTEINDEX(7));
CPen whitePen;
CPen blackPen;
CPen *oldPen;

	whitePen.CreatePen(PS_SOLID,1, PALETTEINDEX(19));
	blackPen.CreatePen(PS_SOLID,1,PALETTEINDEX(0));

	size = dc->GetOutputTextExtent(lpszText, nCount);
	int addx = (rect.right - rect.left - size.cx) / 2;
	int addy = (rect.bottom - rect.top - size.cy) / 2 + 1;
	
	if(isGrey)
	{
		oldColor = dc->SetBkColor(PALETTEINDEX(7));
		dc->FillRect(&rect, &greyBrush);
	}
	dc->ExtTextOut(rect.left+addx, rect.top+addy,
					ETO_CLIPPED,
					&rect,
					lpszText,
					nCount,
					NULL);
	if(isGrey)
	{
		oldPen = dc->SelectObject(&blackPen);
	    dc->MoveTo(rect.right,rect.bottom);
	    dc->LineTo(rect.right,rect.top);
	    dc->LineTo(rect.left,rect.top);
	    dc->LineTo(rect.left,rect.bottom);
	    dc->SelectObject(&whitePen);
	    dc->MoveTo(rect.right-1,rect.top+1);
		dc->LineTo(rect.left+1,rect.top+1);
		dc->LineTo(rect.left+1,rect.bottom);

		dc->SetBkColor(oldColor);
		dc->SelectObject(oldPen);
	}
}

void CMemoryWindow::FillText2(LPCSTR lpszText,UINT nCount,RECT rect,CDC* dc)
{
SIZE size;
char text[256];

	nCount=min(nCount, 255);
	memcpy(text, lpszText, nCount);
	memset(&text[nCount],' ',255-nCount);
	text[255]=NULL;
	size = dc->GetOutputTextExtent(lpszText, nCount);
	int addx = m_nCharWidth/2;
	int addy = (rect.bottom - rect.top - size.cy) / 2 + 1;
	dc->ExtTextOut(rect.left+addx, rect.top+addy,
	               ETO_CLIPPED,
	               &rect,
	               text,
	               255,
	               NULL);
}

void CMemoryWindow::SetScrollBar()
{
RECT rect1,rect2;

	GetClientRect(&rect2);
    
	if (m_bViewMode2 != SM_CODE)
	{
		if (m_bShowAscii)
		{
			rect1 = m_gridAscii.GetGridRect(0,0);
			if (rect1.right >= rect2.right)
				m_bHScrollOn = TRUE;
			else
			    m_bHScrollOn = FALSE;
		}
		else
		{
			rect1 = m_gridMem.GetGridRect(m_gridMem.m_nRows-1,0);
			if (rect1.right >= rect2.right)
				m_bHScrollOn = TRUE;
			else
				m_bHScrollOn = FALSE;
		}
	}
	else
	{
		rect1 = m_gridInstruction.GetGridRect(0,0);
		if (rect1.right >= rect2.right)
			m_bHScrollOn = TRUE;
		else
			m_bHScrollOn = FALSE;
	}
	if (m_nPosX<0)
	{
		if (rect2.right>rect1.right)
		{
			m_nPosX = m_nPosX + (rect2.right-rect1.right);
			if (m_nPosX>0)
				m_nPosX = 0;
		}
	}
	else 
		m_nPosX = 0;
	if (m_nPosX<0) 
		m_bHScrollOn = TRUE;
	ShowScrollBar(SB_HORZ, m_bHScrollOn);
	if (m_bHScrollOn)
	{
		SetScrollRange(SB_HORZ, 0, 
					(rect1.right-rect2.right-m_nPosX+3),FALSE);
		SetScrollPos(SB_HORZ, -m_nPosX, TRUE);
	}
}

void CMemoryWindow::SetAddress()
{
	m_gridAddr.SetPos(0,0,0);
	m_gridAddr.SetLines(m_nLines);
	m_gridAddr.SetRows(1);
	m_gridAddr.SetGridWidth(m_nCharWidth*5);
	m_gridAddr.SetGridHeight(m_nLineHeight);
	memcpy(m_gridAddr.m_lpszTitle,"Addr\0",8);
	m_gridAddr.DoRect();
}

void CMemoryWindow::SetAscii()
{
	m_gridAscii.SetPos(m_gridMem.m_rectPos.right,0, m_gridAddr.m_nGridWidth);
	m_gridAscii.SetLines(m_nLines);
	m_gridAscii.SetRows(1);
	m_gridAscii.SetGridWidth(m_nCharWidth*(16/m_nLineGroup+1));
	m_gridAscii.SetGridHeight(m_nLineHeight);
	memcpy(m_gridAscii.m_lpszTitle,"ASCII\0",6);
	m_gridAscii.DoRect();
}

void CMemoryWindow::SetInstruction()
{
	m_gridInstruction.SetPos(m_gridMem.m_rectPos.right,0,
				m_gridAddr.m_nGridWidth);
	m_gridInstruction.SetLines(m_nLines);
	m_gridInstruction.SetRows(1);
	m_gridInstruction.SetGridWidth(m_nCharWidth*256);
	m_gridInstruction.SetGridHeight(m_nLineHeight);
	memcpy(m_gridInstruction.m_lpszTitle,"Instruction\0",12);
	m_gridInstruction.DoRect();
}

void CMemoryWindow::SetByteSignedDecimal()
{
	m_gridMem.SetPos(m_nPosX,0, m_gridAddr.m_nGridWidth);
	m_gridMem.SetLines(m_nLines);
	m_gridMem.SetRows(16/m_nLineGroup);
	m_gridMem.SetGridWidth(m_nCharWidth*5);
	m_gridMem.SetGridHeight(m_nLineHeight);
	m_gridMem.m_lpszTitle[0]='0';
	m_gridMem.m_lpszTitle[1]='\0';
	m_gridMem.m_lpszTitle[2]='1';
	m_gridMem.m_lpszTitle[3]='\0';
	m_gridMem.m_lpszTitle[4]='2';
	m_gridMem.m_lpszTitle[5]='\0';
	m_gridMem.m_lpszTitle[6]='3';
	m_gridMem.m_lpszTitle[7]='\0';
	m_gridMem.m_lpszTitle[8]='4';
	m_gridMem.m_lpszTitle[9]='\0';
	m_gridMem.m_lpszTitle[10]='5';
	m_gridMem.m_lpszTitle[11]='\0';
	m_gridMem.m_lpszTitle[12]='6';
	m_gridMem.m_lpszTitle[13]='\0';
	m_gridMem.m_lpszTitle[14]='7';
	m_gridMem.m_lpszTitle[15]='\0';
	m_gridMem.m_lpszTitle[16]='8';
	m_gridMem.m_lpszTitle[17]='\0';
	m_gridMem.m_lpszTitle[18]='9';
	m_gridMem.m_lpszTitle[19]='\0';
	m_gridMem.m_lpszTitle[20]='A';
	m_gridMem.m_lpszTitle[21]='\0';
	m_gridMem.m_lpszTitle[22]='B';
	m_gridMem.m_lpszTitle[23]='\0';
	m_gridMem.m_lpszTitle[24]='C';
	m_gridMem.m_lpszTitle[25]='\0';
	m_gridMem.m_lpszTitle[26]='D';
	m_gridMem.m_lpszTitle[27]='\0';
	m_gridMem.m_lpszTitle[28]='E';
	m_gridMem.m_lpszTitle[29]='\0';
	m_gridMem.m_lpszTitle[30]='F';
	m_gridMem.m_lpszTitle[31]='\0';
	m_gridMem.DoRect();
}

void CMemoryWindow::SetWordSignedDecimal()
{
	m_gridMem.SetPos(m_nPosX,0, m_gridAddr.m_nGridWidth);
	m_gridMem.SetLines(m_nLines);
	m_gridMem.SetRows(8/m_nLineGroup);
	m_gridMem.SetGridWidth(m_nCharWidth*7);
	m_gridMem.SetGridHeight(m_nLineHeight);
	m_gridMem.m_lpszTitle[0]='0';
	m_gridMem.m_lpszTitle[1]='\0';
	m_gridMem.m_lpszTitle[2]='2';
	m_gridMem.m_lpszTitle[3]='\0';
	m_gridMem.m_lpszTitle[4]='4';
	m_gridMem.m_lpszTitle[5]='\0';
	m_gridMem.m_lpszTitle[6]='6';
	m_gridMem.m_lpszTitle[7]='\0';
	m_gridMem.m_lpszTitle[8]='8';
	m_gridMem.m_lpszTitle[9]='\0';
	m_gridMem.m_lpszTitle[10]='A';
	m_gridMem.m_lpszTitle[11]='\0';
	m_gridMem.m_lpszTitle[12]='C';
	m_gridMem.m_lpszTitle[13]='\0';
	m_gridMem.m_lpszTitle[14]='E';
	m_gridMem.m_lpszTitle[15]='\0';
	m_gridMem.DoRect();
}

void CMemoryWindow::SetLongSignedDecimal()
{
	m_gridMem.SetPos(m_nPosX,0, m_gridAddr.m_nGridWidth);
	m_gridMem.SetLines(m_nLines);
	m_gridMem.SetRows(4/m_nLineGroup);
	m_gridMem.SetGridWidth(m_nCharWidth*12);
	m_gridMem.SetGridHeight(m_nLineHeight);
	m_gridMem.m_lpszTitle[0]='0';
	m_gridMem.m_lpszTitle[1]='\0';
	m_gridMem.m_lpszTitle[2]='4';
	m_gridMem.m_lpszTitle[3]='\0';
	m_gridMem.m_lpszTitle[4]='8';
	m_gridMem.m_lpszTitle[5]='\0';
	m_gridMem.m_lpszTitle[6]='C';
	m_gridMem.m_lpszTitle[7]='\0';
	m_gridMem.DoRect();
}

void CMemoryWindow::SetByteUnsignedDecimal()
{
	m_gridMem.SetPos(m_nPosX,0, m_gridAddr.m_nGridWidth);
	m_gridMem.SetLines(m_nLines);
	m_gridMem.SetRows(16/m_nLineGroup);
	m_gridMem.SetGridWidth(m_nCharWidth*4);
	m_gridMem.SetGridHeight(m_nLineHeight);
	m_gridMem.m_lpszTitle[0]='0';
	m_gridMem.m_lpszTitle[1]='\0';
	m_gridMem.m_lpszTitle[2]='1';
	m_gridMem.m_lpszTitle[3]='\0';
	m_gridMem.m_lpszTitle[4]='2';
	m_gridMem.m_lpszTitle[5]='\0';
	m_gridMem.m_lpszTitle[6]='3';
	m_gridMem.m_lpszTitle[7]='\0';
	m_gridMem.m_lpszTitle[8]='4';
	m_gridMem.m_lpszTitle[9]='\0';
	m_gridMem.m_lpszTitle[10]='5';
	m_gridMem.m_lpszTitle[11]='\0';
	m_gridMem.m_lpszTitle[12]='6';
	m_gridMem.m_lpszTitle[13]='\0';
	m_gridMem.m_lpszTitle[14]='7';
	m_gridMem.m_lpszTitle[15]='\0';
	m_gridMem.m_lpszTitle[16]='8';
	m_gridMem.m_lpszTitle[17]='\0';
	m_gridMem.m_lpszTitle[18]='9';
	m_gridMem.m_lpszTitle[19]='\0';
	m_gridMem.m_lpszTitle[20]='A';
	m_gridMem.m_lpszTitle[21]='\0';
	m_gridMem.m_lpszTitle[22]='B';
	m_gridMem.m_lpszTitle[23]='\0';
	m_gridMem.m_lpszTitle[24]='C';
	m_gridMem.m_lpszTitle[25]='\0';
	m_gridMem.m_lpszTitle[26]='D';
	m_gridMem.m_lpszTitle[27]='\0';
	m_gridMem.m_lpszTitle[28]='E';
	m_gridMem.m_lpszTitle[29]='\0';
	m_gridMem.m_lpszTitle[30]='F';
	m_gridMem.m_lpszTitle[31]='\0';
	m_gridMem.DoRect();
}

void CMemoryWindow::SetWordUnsignedDecimal()
{
	m_gridMem.SetPos(m_nPosX,0, m_gridAddr.m_nGridWidth);
	m_gridMem.SetLines(m_nLines);
	m_gridMem.SetRows(8/m_nLineGroup);
	m_gridMem.SetGridWidth(m_nCharWidth*6);
	m_gridMem.SetGridHeight(m_nLineHeight);
	m_gridMem.m_lpszTitle[0]='0';
	m_gridMem.m_lpszTitle[1]='\0';
	m_gridMem.m_lpszTitle[2]='2';
	m_gridMem.m_lpszTitle[3]='\0';
	m_gridMem.m_lpszTitle[4]='4';
	m_gridMem.m_lpszTitle[5]='\0';
	m_gridMem.m_lpszTitle[6]='6';
	m_gridMem.m_lpszTitle[7]='\0';
	m_gridMem.m_lpszTitle[8]='8';
	m_gridMem.m_lpszTitle[9]='\0';
	m_gridMem.m_lpszTitle[10]='A';
	m_gridMem.m_lpszTitle[11]='\0';
	m_gridMem.m_lpszTitle[12]='C';
	m_gridMem.m_lpszTitle[13]='\0';
	m_gridMem.m_lpszTitle[14]='E';
	m_gridMem.m_lpszTitle[15]='\0';
	m_gridMem.DoRect();
}

void CMemoryWindow::SetLongUnsignedDecimal()
{
	m_gridMem.SetPos(m_nPosX,0, m_gridAddr.m_nGridWidth);
	m_gridMem.SetLines(m_nLines);
	m_gridMem.SetRows(4/m_nLineGroup);
	m_gridMem.SetGridWidth(m_nCharWidth*11);
	m_gridMem.SetGridHeight(m_nLineHeight);
	m_gridMem.m_lpszTitle[0]='0';
	m_gridMem.m_lpszTitle[1]='\0';
	m_gridMem.m_lpszTitle[2]='4';
	m_gridMem.m_lpszTitle[3]='\0';
	m_gridMem.m_lpszTitle[4]='8';
	m_gridMem.m_lpszTitle[5]='\0';
	m_gridMem.m_lpszTitle[6]='C';
	m_gridMem.m_lpszTitle[7]='\0';
	m_gridMem.DoRect();
}

void CMemoryWindow::SetByteHexadecimal()
{
	m_gridMem.SetPos(m_nPosX,0, m_gridAddr.m_nGridWidth);
	m_gridMem.SetLines(m_nLines);
	m_gridMem.SetRows(16/m_nLineGroup);
	m_gridMem.SetGridWidth(m_nCharWidth*3);
	m_gridMem.SetGridHeight(m_nLineHeight);
	m_gridMem.m_lpszTitle[0]='0';
	m_gridMem.m_lpszTitle[1]='\0';
	m_gridMem.m_lpszTitle[2]='1';
	m_gridMem.m_lpszTitle[3]='\0';
	m_gridMem.m_lpszTitle[4]='2';
	m_gridMem.m_lpszTitle[5]='\0';
	m_gridMem.m_lpszTitle[6]='3';
	m_gridMem.m_lpszTitle[7]='\0';
	m_gridMem.m_lpszTitle[8]='4';
	m_gridMem.m_lpszTitle[9]='\0';
	m_gridMem.m_lpszTitle[10]='5';
	m_gridMem.m_lpszTitle[11]='\0';
	m_gridMem.m_lpszTitle[12]='6';
	m_gridMem.m_lpszTitle[13]='\0';
	m_gridMem.m_lpszTitle[14]='7';
	m_gridMem.m_lpszTitle[15]='\0';
	m_gridMem.m_lpszTitle[16]='8';
	m_gridMem.m_lpszTitle[17]='\0';
	m_gridMem.m_lpszTitle[18]='9';
	m_gridMem.m_lpszTitle[19]='\0';
	m_gridMem.m_lpszTitle[20]='A';
	m_gridMem.m_lpszTitle[21]='\0';
	m_gridMem.m_lpszTitle[22]='B';
	m_gridMem.m_lpszTitle[23]='\0';
	m_gridMem.m_lpszTitle[24]='C';
	m_gridMem.m_lpszTitle[25]='\0';
	m_gridMem.m_lpszTitle[26]='D';
	m_gridMem.m_lpszTitle[27]='\0';
	m_gridMem.m_lpszTitle[28]='E';
	m_gridMem.m_lpszTitle[29]='\0';
	m_gridMem.m_lpszTitle[30]='F';
	m_gridMem.m_lpszTitle[31]='\0';
	m_gridMem.DoRect();
}

void CMemoryWindow::SetWordHexadecimal()
{
	m_gridMem.SetPos(m_nPosX,0, m_gridAddr.m_nGridWidth);
	m_gridMem.SetLines(m_nLines);
	m_gridMem.SetRows(8/m_nLineGroup);
	m_gridMem.SetGridWidth(m_nCharWidth*5);
	m_gridMem.SetGridHeight(m_nLineHeight);
	m_gridMem.m_lpszTitle[0]='0';
	m_gridMem.m_lpszTitle[1]='\0';
	m_gridMem.m_lpszTitle[2]='2';
	m_gridMem.m_lpszTitle[3]='\0';
	m_gridMem.m_lpszTitle[4]='4';
	m_gridMem.m_lpszTitle[5]='\0';
	m_gridMem.m_lpszTitle[6]='6';
	m_gridMem.m_lpszTitle[7]='\0';
	m_gridMem.m_lpszTitle[8]='8';
	m_gridMem.m_lpszTitle[9]='\0';
	m_gridMem.m_lpszTitle[10]='A';
	m_gridMem.m_lpszTitle[11]='\0';
	m_gridMem.m_lpszTitle[12]='C';
	m_gridMem.m_lpszTitle[13]='\0';
	m_gridMem.m_lpszTitle[14]='E';
	m_gridMem.m_lpszTitle[15]='\0';
	m_gridMem.DoRect();
}

void CMemoryWindow::SetLongHexadecimal()
{
	m_gridMem.SetPos(m_nPosX,0, m_gridAddr.m_nGridWidth);
	m_gridMem.SetLines(m_nLines);
	m_gridMem.SetRows(4/m_nLineGroup);
	m_gridMem.SetGridWidth(m_nCharWidth*9);
	m_gridMem.SetGridHeight(m_nLineHeight);
	m_gridMem.m_lpszTitle[0]='0';
	m_gridMem.m_lpszTitle[1]='\0';
	m_gridMem.m_lpszTitle[2]='4';
	m_gridMem.m_lpszTitle[3]='\0';
	m_gridMem.m_lpszTitle[4]='8';
	m_gridMem.m_lpszTitle[5]='\0';
	m_gridMem.m_lpszTitle[6]='C';
	m_gridMem.m_lpszTitle[7]='\0';
	m_gridMem.DoRect();
}

void CMemoryWindow::SetDisassemble()
{
	m_gridMem.SetPos(m_nPosX,0, m_gridAddr.m_nGridWidth);
	m_gridMem.SetLines(m_nLines);
	m_gridMem.SetRows(1);
	m_gridMem.SetGridWidth(m_nCharWidth*11);
	m_gridMem.SetGridHeight(m_nLineHeight);
	m_gridMem.m_lpszTitle[0]='O';
	m_gridMem.m_lpszTitle[1]='P';
	m_gridMem.m_lpszTitle[2]=' ';
	m_gridMem.m_lpszTitle[3]='c';
	m_gridMem.m_lpszTitle[4]='o';
	m_gridMem.m_lpszTitle[5]='d';
	m_gridMem.m_lpszTitle[6]='e';
	m_gridMem.m_lpszTitle[7]='\0';
	m_gridMem.DoRect();
}

void CMemoryWindow::SetMemoryWindow()
{
	SetAddress();

	switch (m_bViewMode2)
	{
		case SM_CODE:
			SetDisassemble();
			break;
		case SM_HEX:
			switch (m_bViewMode1)
			{
				case SM_BYTE:
					SetByteHexadecimal();
					break;
				case SM_WORD:
					SetWordHexadecimal();
					break;
				case SM_DWORD:
					SetLongHexadecimal();
					break;
				default:
					break;
			}
			break;
		case SM_UDEC:
			switch (m_bViewMode1)
			{
				case SM_BYTE:
					SetByteUnsignedDecimal();
					break;
				case SM_WORD:
					SetWordUnsignedDecimal();
					break;
				case SM_DWORD:
					SetLongUnsignedDecimal();
					break;
				default:
					break;
			}
			break;
		case SM_DEC:
			switch (m_bViewMode1)
			{
				case SM_BYTE:
					SetByteSignedDecimal();
					break;
				case SM_WORD:
					SetWordSignedDecimal();
					break;
				case SM_DWORD:
					SetLongSignedDecimal();
					break;
				default:
					break;
			}
			break;
		default:
			break;
	}
	if (m_bViewMode2!=SM_CODE)
	{
		if (m_bShowAscii)
			SetAscii();
	}
	else
		SetInstruction();
}

void CMemoryWindow::ShowAddress(CDC *dc)
{
RECT rect;
int i;
char buf[20];
long addr;

	if(m_bViewMode2!=SM_CODE)
	{
		ASSERT(m_dwStartAddress%(0x10/m_nLineGroup)==0);
		addr = m_dwStartAddress;
		for( i = 1; i < m_nLines; i++ )
		{
			rect = m_gridAddr.GetGridRect(0,i);
			sprintf(buf,"%04X",addr);       // modified by Daniel
			FillText(buf,4,rect,dc, TRUE);        // modified by Daniel
			addr+=(0x10/m_nLineGroup);
		}
	}
	else		//Dissemble
	{
		for(i=1;i<=m_nDSMNum;i++)
		{
			rect = m_gridAddr.GetGridRect(0,i);
			sprintf(buf, "%04X", m_dsm[i-1].address);
			FillText(buf,4,rect,dc, TRUE);
		}
	}
}

void CMemoryWindow::ShowAscii(CDC *dc)
{
RECT rect;
int i,j,pos;
BYTE value;
BYTE *p;
char buf[20];

	p = (BYTE *)m_byMem;
	for ( i = 1; i < m_nLines; i++ )
	{
		rect = m_gridAscii.GetGridRect(0, i);
		for (j = 0; j < 16/m_nLineGroup; j++ )
		{
			pos = (i-1) * (16/m_nLineGroup) + j;
			value = p[pos];
			if ((0x20 < value) && (value <= 0x7e))
				buf[j]=value;
			else
				buf[j]='.';
		}
		FillText(buf,16/m_nLineGroup,rect,dc);
	}
}

void CMemoryWindow::ShowInstruction(CDC *dc)
{
RECT rect;
int i;
int j;

	for(i=1;i<=m_nDSMNum;i++)
	{
		rect = m_gridInstruction.GetGridRect(0,i);
		j = strlen(m_dsm[i-1].instruction);
		FillText2((const char*)m_dsm[i-1].instruction,j,rect,dc);
	}
}

void CMemoryWindow::ShowByteSignedDecimal(CDC *dc)
{
RECT rect;
int i,j,pos;
BYTE value;
int	nvalue;
BYTE *p;
char buf[20];

	p = (BYTE *)m_byMem;
	for(i=1;i<m_nLines;i++)
	{
		for(j=0;j<(16/m_nLineGroup);j++)
		{
			rect = m_gridMem.GetGridRect(j,i);
			pos = (i-1)*(16/m_nLineGroup) + j;
			value = p[pos];
			nvalue=(char)value;
			sprintf(buf,"%+04d", nvalue);
			FillText(buf,4,rect,dc);
		}
	}
}

void CMemoryWindow::ShowWordSignedDecimal(CDC *dc)
{
RECT rect;
int i,j,pos;
WORD value;
WORD *p;
char buf[20];

	p = (WORD *)m_byMem;
	for(i=1;i<m_nLines;i++)
	{
		for(j=0;j<(8/m_nLineGroup);j++)
		{
			rect = m_gridMem.GetGridRect(j,i);
			pos = (i-1)*(8/m_nLineGroup) + j;
			value = p[pos];
			sprintf(buf,"%+06d",value);
			FillText(buf,6,rect,dc);
		}
	}
}

void CMemoryWindow::ShowLongSignedDecimal(CDC *dc)
{
RECT rect;
int i,j,pos;
long value;
long *p;
char buf[20];

	p = (long *)m_byMem;
	for(i=1;i<m_nLines;i++)
	{
		for(j=0;j<(4/m_nLineGroup);j++)
		{
			rect = m_gridMem.GetGridRect(j,i);
			pos = (i-1)*(4/m_nLineGroup) + j;
			value = p[pos];
			sprintf(buf,"%+011ld",value);
			FillText(buf,11,rect,dc);
		}
	}
}

void CMemoryWindow::ShowByteUnsignedDecimal(CDC *dc)
{
RECT rect;
int i,j,pos;
BYTE value;
BYTE *p;
char buf[20];

	p = (BYTE *)m_byMem;
	for(i=1;i<m_nLines;i++)
	{
		for(j=0;j<(16/m_nLineGroup);j++)
		{
			rect = m_gridMem.GetGridRect(j,i);
			pos = (i-1)*(16/m_nLineGroup) + j;
			value = p[pos];
			sprintf(buf,"%03u",value);
			FillText(buf,3,rect,dc);
		}
	}
}

void CMemoryWindow::ShowWordUnsignedDecimal(CDC *dc)
{
RECT rect;
int i,j,pos;
WORD value;
WORD *p;
char buf[20];

	p = (WORD *)m_byMem;
	for(i=1;i<m_nLines;i++)
	{
		for(j=0;j<(8/m_nLineGroup);j++)
		{
			rect = m_gridMem.GetGridRect(j,i);
			pos = (i-1)*(8/m_nLineGroup) + j;
			value = p[pos];
			sprintf(buf,"%05u",value);
			FillText(buf,5,rect,dc);
		}
	}
}

void CMemoryWindow::ShowLongUnsignedDecimal(CDC *dc)
{
RECT rect;
int i,j,pos;
long value;
long *p;
char buf[20];

	p = (long *)m_byMem;
	for(i=1;i<m_nLines;i++)
	{
		for(j=0;j<(4/m_nLineGroup);j++)
		{
			rect = m_gridMem.GetGridRect(j,i);
			pos = (i-1)*(4/m_nLineGroup) + j;
			value = p[pos];
			sprintf(buf,"%010lu",value);
			FillText(buf,10,rect,dc);
		}
	}
}

void CMemoryWindow::ShowByteHexadecimal(CDC *dc)
{
RECT rect;
int i,j;
BYTE value;
int pos;
char buf[20];

	for(i=1;i<m_nLines;i++)
	{
		for(j=0;j<(16/m_nLineGroup);j++)
		{
			rect = m_gridMem.GetGridRect(j,i);
			pos = (i-1)*(16/m_nLineGroup) + j;
			value = m_byMem[pos];
			sprintf(buf,"%02X",value);
			FillText(buf,2,rect,dc);
		}
	}
}

void CMemoryWindow::ShowWordHexadecimal(CDC *dc)
{
RECT rect;
int i,j,pos;
WORD value;
WORD *p;
char buf[20];

	p = (WORD *)m_byMem;
	for(i=1;i<m_nLines;i++)
	{
		for(j=0;j<(8/m_nLineGroup);j++)
		{
			rect = m_gridMem.GetGridRect(j,i);
			pos = (i-1)*(8/m_nLineGroup) + j;
			value = p[pos];
			sprintf(buf,"%04X",value);
			FillText(buf,4,rect,dc);
		}
	}
}

void CMemoryWindow::ShowLongHexadecimal(CDC *dc)
{
RECT rect;
int i,j,pos;
long value;
long *p;
char buf[20];

	p = (long *)m_byMem;
	for(i=1;i<m_nLines;i++)
	{
		for(j=0;j<(4/m_nLineGroup);j++)
		{
			rect = m_gridMem.GetGridRect(j,i);
			pos = (i-1)*(4/m_nLineGroup) + j;
			value = p[pos];
			sprintf(buf,"%08lX",value);
			FillText(buf,8,rect,dc);
		}
	}
}

void CMemoryWindow::ShowDisassemble(CDC *dc)
{
RECT rect;
int i;
int j;

	for(i=1;i<=m_nDSMNum;i++)
	{
		rect = m_gridMem.GetGridRect(0,i);
		j = strlen(m_dsm[i-1].code);
		FillText2(m_dsm[i-1].code,j,rect,dc);
	}
}

void CMemoryWindow::ShowMemoryWindow(CDC *dc)
{
	switch (m_bViewMode2)
	{
		case SM_CODE:
			ShowDisassemble(dc);
			break;
		case SM_HEX:
			switch (m_bViewMode1)
			{
				case SM_BYTE:
					ShowByteHexadecimal(dc);
					break;
				case SM_WORD:
					ShowWordHexadecimal(dc);
					break;
				case SM_DWORD:
					ShowLongHexadecimal(dc);
					break;
				default:
					break;
			}
			break;
		case SM_UDEC:
			switch (m_bViewMode1)
			{
				case SM_BYTE:
					ShowByteUnsignedDecimal(dc);
					break;
				case SM_WORD:
					ShowWordUnsignedDecimal(dc);
					break;
				case SM_DWORD:
					ShowLongUnsignedDecimal(dc);
					break;
				default:
					break;
			}
			break;
		case SM_DEC:
			switch (m_bViewMode1)        
			{
				case SM_BYTE:
					ShowByteSignedDecimal(dc);
					break;
				case SM_WORD:
					ShowWordSignedDecimal(dc);
					break;
				case SM_DWORD:
					ShowLongSignedDecimal(dc);
					break;
				default:
					break;
			}
			break;
		default:
			break;
	}

	if (m_bViewMode2!=SM_CODE)
	{
		if (m_bShowAscii)
			ShowAscii(dc);
	}
	else 
		ShowInstruction(dc);
	ShowAddress(dc);
}

void CMemoryWindow::SetMyCaretPos()
{
WORD wValue;
int i;
RECT rect;
POINT pos;

	if (!m_bFocus) return;

	if (m_bViewMode2==SM_CODE)	//no caret in this mode
	{
		pos.x = -30;
		pos.y = -30;
		SetCaretPos(pos);
	}
	else
	{
		switch (m_nCaretArea)
		{
		case 2:		//in ascii area
            wValue = WORD(m_dwStartAddress/(16/m_nLineGroup));
			if ((m_wCaretPosY>=wValue)&&(m_wCaretPosY<(wValue+m_nLines)))
			{
				i = m_wCaretPosY - wValue;
				rect = m_gridAscii.GetGridRect(0,i+1);
				pos.x = rect.left+m_wCaretPosX2*m_nCharWidth+m_nCharWidth/2-1;
				pos.y = rect.top + 2;
				SetCaretPos(pos);
				ShowCaret();
			}
			else
			{
				pos.x = -30;
				pos.y = -30;
				SetCaretPos(pos);
			}
			break;

		default:		//not in Ascii
			ASSERT(m_dwStartAddress<0x100000);
			wValue = WORD(m_dwStartAddress/(16/m_nLineGroup));
			if ((m_wCaretPosY>=wValue)&&(m_wCaretPosY<(wValue+m_nLines)))
			{
				i = m_wCaretPosY - wValue;
				rect = m_gridMem.GetGridRect(m_wCaretPosX1,i+1);
				pos.x = rect.left+m_wCaretPosX2*m_nCharWidth+m_nCharWidth/2-1;
				if(pos.x<m_gridAddr.m_nGridWidth)
					pos.x=-30;
				pos.y = rect.top + 2;
				SetCaretPos(pos);
				ShowCaret();
			}
			else
			{
				pos.x = -30;
				pos.y = -30;
				SetCaretPos(pos);
			}
			break;
		}
	}
}

void CMemoryWindow::GotoCursor()
{
	OnVScroll(SB_THUMBPOSITION, m_wCaretPosY, NULL);
}

void CMemoryWindow::xGotoCursor(void)
{
int virtualx;
RECT rect;
	
	if(m_bViewMode2==SM_CODE)
		return;
	if(m_nCaretArea==2)			//in Ascii
		virtualx=m_gridAscii.GetLeftPos()+
				 m_nCharWidth*m_wCaretPosX2+m_nCharWidth/2;
	else
	{
		rect=m_gridMem.GetGridRect(m_wCaretPosX1,0);
		virtualx=rect.left+m_wCaretPosX2*m_nCharWidth;
	}
	GetClientRect(&rect);
	if(virtualx+m_nCharWidth>=rect.right||virtualx<m_gridAddr.m_nGridWidth)
	{
		if(virtualx+m_nCharWidth>=rect.right)
		{
			virtualx+=m_nCharWidth*2;
			OnHScroll(SB_THUMBTRACK, virtualx-rect.right-m_nPosX, NULL);
		}
		else
		{
			virtualx-=m_nCharWidth;
			OnHScroll(SB_THUMBTRACK, max(0, virtualx-m_nPosX-
						m_gridAddr.m_nGridWidth), NULL);
		}
	}
}

BOOL CMemoryWindow::InWnd()
{
UINT i;

	i = (UINT)(m_dwStartAddress/(16/m_nLineGroup));
	if((m_wCaretPosY>=i)&&(m_wCaretPosY<(i+m_nLines-2)))
		return TRUE;
	else
		return FALSE;
}

void CMemoryWindow::PaintLine(WORD line)
{
	ASSERT(line>=0&&line<WORD(m_nLines));
	
RECT rect, rectwnd;
	
	rect=m_gridAddr.GetGridRect(0, line+1);
	GetClientRect(&rectwnd);
	rectwnd.top=rect.top;
	rectwnd.bottom=rect.bottom;
	InvalidateRect(&rectwnd);
}

void CMemoryWindow::Right()
{
	if (m_nCaretArea == 2)
	{
		if (m_wCaretPosX2==WORD(16/m_nLineGroup-1))
		{
			if(m_wCaretPosY==m_dwMemRegionEnd/(16/m_nLineGroup))
			{
				MessageBeep(-1);
				return;
			}
			m_wCaretPosX2=0;
			Down();
			return;
		}
		else
			m_wCaretPosX2++;
	}
	else
		switch(m_bViewMode2)
		{
		case SM_CODE:            // Disassembly
			break;

		case SM_HEX:            // Hexdecimal
			switch(m_bViewMode1)
			{
				case SM_BYTE:             // Byte
					if ((m_wCaretPosX1==(16/m_nLineGroup-1))&&(m_wCaretPosX2==1))
					{
						if(m_wCaretPosY==m_dwMemRegionEnd/(16/m_nLineGroup))
						{
							MessageBeep(-1);
							return;
						}
						m_wCaretPosX1 = 0;
						m_wCaretPosX2 = 0;
						Down();
						return;
					}
					if (m_wCaretPosX2==1)
					{
						m_wCaretPosX1++;
						m_wCaretPosX2=0;
					}
					else
						m_wCaretPosX2++;
					break;
			    case SM_WORD:             // Word
					if ((m_wCaretPosX1==(8/m_nLineGroup-1))&&(m_wCaretPosX2==3))
					{
						if(m_wCaretPosY==m_dwMemRegionEnd/(16/m_nLineGroup))
						{
							MessageBeep(-1);
							return;
						}
						m_wCaretPosX1 = 0;
						m_wCaretPosX2 = 0;
						Down();
						return;
					}
					if (m_wCaretPosX2==3)
					{
						m_wCaretPosX1++;
						m_wCaretPosX2=0;
					}
					else
						m_wCaretPosX2++;
					break;
			    case SM_DWORD:             // Long
					if ((m_wCaretPosX1==(4/m_nLineGroup-1))&&(m_wCaretPosX2==7))
					{
						if(m_wCaretPosY==m_dwMemRegionEnd/(16/m_nLineGroup))
						{
							MessageBeep(-1);
							return;
						}
						m_wCaretPosX1 = 0;
						m_wCaretPosX2 = 0;
						Down();
						return;
					}
					if (m_wCaretPosX2==7)
					{
						m_wCaretPosX1++;
						m_wCaretPosX2=0;
					}
					else
						m_wCaretPosX2++;
					break;
				default:
					break;
			}
			break;

		case SM_UDEC:            // Unsigned Decimal
			switch(m_bViewMode1)
			{
				case SM_BYTE:          // Byte
					if ((m_wCaretPosX1==(16/m_nLineGroup-1))&&(m_wCaretPosX2==2))
					{
						if(m_wCaretPosY==m_dwMemRegionEnd/(16/m_nLineGroup))
						{
							MessageBeep(-1);
							return;
						}
						m_wCaretPosX1 = 0;
						m_wCaretPosX2 = 0;
						Down();
					    return;
					}
					if (m_wCaretPosX2==2)
					{
						m_wCaretPosX1++;
						m_wCaretPosX2=0;
					}
					else
						m_wCaretPosX2++;
					break;        
				case SM_WORD:           // Word
					if ((m_wCaretPosX1==(8/m_nLineGroup-1))&&(m_wCaretPosX2==4))
					{
						if(m_wCaretPosY==m_dwMemRegionEnd/(16/m_nLineGroup))
						{
							MessageBeep(-1);
							return;
						}
						m_wCaretPosX1 = 0;
						m_wCaretPosX2 = 0;
						Down();
						return;
					}
					if (m_wCaretPosX2==4)
					{
						m_wCaretPosX1++;
						m_wCaretPosX2=0;
					}
					else
						m_wCaretPosX2++;
					break;
				case SM_DWORD:          // Long
					if ((m_wCaretPosX1==(4/m_nLineGroup-1))&&(m_wCaretPosX2==9))
					{
						if(m_wCaretPosY==m_dwMemRegionEnd/(16/m_nLineGroup))
						{
							MessageBeep(-1);
							return;
						}
						m_wCaretPosX1 = 0;
						m_wCaretPosX2 = 0;
						Down();
						return;
					}
					if (m_wCaretPosX2==9)
					{
						m_wCaretPosX1++;
						m_wCaretPosX2=0;
					}
					else
						m_wCaretPosX2++;
					break;
				default:
					break;
			}
			break;

		case SM_DEC:         // Signed Decimal
			switch(m_bViewMode1)
			{
				case SM_BYTE:          // Byte
					if ((m_wCaretPosX1==(16/m_nLineGroup-1))&&(m_wCaretPosX2==3))
					{
						if(m_wCaretPosY==m_dwMemRegionEnd/(16/m_nLineGroup))
						{
							MessageBeep(-1);
							return;
						}
						m_wCaretPosX1 = 0;
						m_wCaretPosX2 = 0;
						Down();
						return;
					}
					if (m_wCaretPosX2==3)
					{
						m_wCaretPosX1++;
						m_wCaretPosX2=0;
					}
					else
						m_wCaretPosX2++;
					break;
				case SM_WORD:       // Word
					if ((m_wCaretPosX1==(8/m_nLineGroup-1))&&(m_wCaretPosX2==5))
					{
						if(m_wCaretPosY==m_dwMemRegionEnd/(16/m_nLineGroup))
						{
							MessageBeep(-1);
							return;
						}
						m_wCaretPosX1 = 0;
						m_wCaretPosX2 = 0;
						Down();
						return;
					}
					if (m_wCaretPosX2==5)
					{
						m_wCaretPosX1++;
						m_wCaretPosX2=0;
					}
					else
						m_wCaretPosX2++;
					break;
				case SM_DWORD:       // Long
					if ((m_wCaretPosX1==(4/m_nLineGroup-1))&&(m_wCaretPosX2==10))
					{
						if(m_wCaretPosY==m_dwMemRegionEnd/(16/m_nLineGroup))
						{
						MessageBeep(-1);
							return;
						}
						m_wCaretPosX1 = 0;
						m_wCaretPosX2 = 0;
						Down();
						return;
					}
					if (m_wCaretPosX2==10)
					{
						m_wCaretPosX1++;
						m_wCaretPosX2=0;
					}
					else
						m_wCaretPosX2++;
					break;
				default:
					break;
			}
			break;  

		default:
		    break;
		}
}

void CMemoryWindow::Left()
{
	if (m_nCaretArea == 2)	//in ascii
	{
		if (m_wCaretPosX2==0)
		{
			if(m_wCaretPosY==0)
			{
				MessageBeep(-1);
				return;
			}
			m_wCaretPosX2=16/m_nLineGroup-1;
			Up();
			return;
		}
		else
			m_wCaretPosX2--;
	}
	else
		switch(m_bViewMode2)
		{
			case SM_CODE:            // Disassembly
				break;                       
			case SM_HEX:            // Hexdecimal
				switch(m_bViewMode1)
				{
					case SM_BYTE:             // Byte
						if ((m_wCaretPosX1==0)&&(m_wCaretPosX2==0))
						{
							if(m_wCaretPosY==0)
							{
								MessageBeep(-1);
								return;
							}
							m_wCaretPosX1 = 16/m_nLineGroup-1;
							m_wCaretPosX2 = 1;
							Up();
							return;
						}
						if (m_wCaretPosX2==0)
						{
						    m_wCaretPosX1--;
						    m_wCaretPosX2=1;
						}
						else
							m_wCaretPosX2--;
						break;
				    case SM_WORD:             // Word
				        if ((m_wCaretPosX1==0)&&(m_wCaretPosX2==0))
				        {
				        	if(m_wCaretPosY==0)
							{
								MessageBeep(-1);
								return;
							}
							m_wCaretPosX1 = 8/m_nLineGroup-1;
				        	m_wCaretPosX2 = 3;
				        	Up();
				        	return;
				        }
				        if (m_wCaretPosX2==0)
				        {
				            m_wCaretPosX1--;
				            m_wCaretPosX2=3;
				        }
				        else
				        	m_wCaretPosX2--;
				        break;
				    case SM_DWORD:             // Long
				        if ((m_wCaretPosX1==0)&&(m_wCaretPosX2==0))
				        {
				            if(m_wCaretPosY==0)
							{
								MessageBeep(-1);
								return;
							}
							m_wCaretPosX1 = 4/m_nLineGroup-1;
				            m_wCaretPosX2 = 7;
				            Up();
				            return;
				        }
				        if (m_wCaretPosX2==0)
				        {
				            m_wCaretPosX1--;
				            m_wCaretPosX2=7;
				        }
				        else
				            m_wCaretPosX2--;
				        break;
				    default:
				        break;
				}
				break;
				
			case SM_UDEC:         // Unsigned decimal
			    switch(m_bViewMode1)
			    {
			        case SM_BYTE:       // Byte
			            if ((m_wCaretPosX1==0)&&(m_wCaretPosX2==0))
			            {
			                if(m_wCaretPosY==0)
							{
								MessageBeep(-1);
								return;
							}
							m_wCaretPosX1 = 16/m_nLineGroup-1;
			                m_wCaretPosX2 = 2;
			                Up();
			                return;
			            }
			            if (m_wCaretPosX2==0)
			            {
			                m_wCaretPosX1--;
			                m_wCaretPosX2=2;
			            }
			            else
			                m_wCaretPosX2--;
			            break;
			        case SM_WORD:       // Word
			            if ((m_wCaretPosX1==0)&&(m_wCaretPosX2==0))
			            {
			                if(m_wCaretPosY==0)
							{
								MessageBeep(-1);
								return;
							}
							m_wCaretPosX1 = 8/m_nLineGroup-1;
			                m_wCaretPosX2 = 4;
			                Up();
			                return;
			            }
			            if (m_wCaretPosX2==0)
			            {
			                m_wCaretPosX1--;
			                m_wCaretPosX2=4;
			            }
			            else
			                m_wCaretPosX2--;
			            break;
			        case SM_DWORD:       // Long
			            if ((m_wCaretPosX1==0)&&(m_wCaretPosX2==0))
			            {
			                if(m_wCaretPosY==0)
							{
								MessageBeep(-1);
								return;
							}
							m_wCaretPosX1 = 4/m_nLineGroup-1;
			                m_wCaretPosX2 = 9;
			                Up();
			                return;
			            }
			            if (m_wCaretPosX2==0)
			            {
			                m_wCaretPosX1--;
			                m_wCaretPosX2=9;
			            }
			            else
			                m_wCaretPosX2--;
			            break;
			        default:
			            break;
			    }
			    break;

			case SM_DEC:            // Decimal
			    switch(m_bViewMode1)
			    {
			        case SM_BYTE:       // Byte
			            if ((m_wCaretPosX1==0)&&(m_wCaretPosX2==0))
			            {
			                if(m_wCaretPosY==0)
							{
								MessageBeep(-1);
								return;
							}
							m_wCaretPosX1 = 16/m_nLineGroup-1;
			                m_wCaretPosX2 = 3;
			                Up();
			                return;
			            }
			            if (m_wCaretPosX2==0)
			            {
			                m_wCaretPosX1--;
			                m_wCaretPosX2=3;
			            }
			            else
			                m_wCaretPosX2--;
			            break;
			        case SM_WORD:       // Word
			            if ((m_wCaretPosX1==0)&&(m_wCaretPosX2==0))
			            {
			                if(m_wCaretPosY==0)
							{
								MessageBeep(-1);
								return;
							}
							m_wCaretPosX1 = 8/m_nLineGroup-1;
			                m_wCaretPosX2 = 5;
			                Up();
			                return;
			            }
			            if (m_wCaretPosX2==0)
			            {
			                m_wCaretPosX1--;
			                m_wCaretPosX2=5;
			            }
			            else
			                m_wCaretPosX2--;
			            break;
			        case SM_DWORD:       // Long
			            if ((m_wCaretPosX1==0)&&(m_wCaretPosX2==0))
			            {
			                if(m_wCaretPosY==0)
							{
								MessageBeep(-1);
								return;
							}
							m_wCaretPosX1 = 4/m_nLineGroup-1;
			                m_wCaretPosX2 = 10;
			                Up();
			                return;
			            }
			            if (m_wCaretPosX2==0)
			            {
			                m_wCaretPosX1--;
			                m_wCaretPosX2=10;
			            }
			            else
			                m_wCaretPosX2--;
			            break;
			        default:
			            break;
			    }
			    break;

			default:
			    break;
		}
}

void CMemoryWindow::Up()
{
	if(0==m_wCaretPosY)
	{
		MessageBeep(-1);
		return;
	}
	m_wCaretPosY--;
}

void CMemoryWindow::Down()
{
	if(m_wCaretPosY>=m_dwMemRegionEnd/(16/m_nLineGroup))
	{
		MessageBeep(-1);
		return;
	}
	m_wCaretPosY++;
	if(m_wCaretPosY==(m_dwStartAddress/(16/m_nLineGroup)+m_nLines-2))
		OnVScroll(SB_LINEDOWN, 0, NULL);
}

void CMemoryWindow::Home()
{
	if(m_wCaretPosX1==0&&m_wCaretPosX2==0&&m_nCaretArea==1)
	{
		OnHScroll(SB_THUMBTRACK, 0, NULL);
		return;
	}
	m_wCaretPosX1=0;
	m_wCaretPosX2=0;
}

void CMemoryWindow::End()
{
	if (m_nCaretArea == 2)
		m_wCaretPosX2=16/m_nLineGroup-1;
	else
		switch(m_bViewMode2)
		{
			case SM_CODE:         // Disassembly
				return;
			case SM_HEX:         // Hexdeciaml
				switch(m_bViewMode1)
				{
					case SM_BYTE:          // Byte
						m_wCaretPosX1=16/m_nLineGroup-1;
						m_wCaretPosX2=1;
						break;
					case SM_WORD:          // Word
						m_wCaretPosX1=8/m_nLineGroup-1;
						m_wCaretPosX2=3;
						break;
					case SM_DWORD:          // Long
						m_wCaretPosX1=4/m_nLineGroup-1;
						m_wCaretPosX2=7;
						break;
					default:         
						break;
				}
				break;

			case SM_UDEC:         // Unsigned decimal
				switch(m_bViewMode1)
				{
					case SM_BYTE:          // Byte
						m_wCaretPosX1=16/m_nLineGroup-1;
						m_wCaretPosX2=2;
						break;
					case SM_WORD:          // Word
						m_wCaretPosX1=8/m_nLineGroup-1;
						m_wCaretPosX2=4;
						break;
					case SM_DWORD:          // Long
						m_wCaretPosX1=4/m_nLineGroup-1;
						m_wCaretPosX2=9;
						break;
					default:
						break;
				}
				break;

			case SM_DEC:         // Signed decimal   
				switch(m_bViewMode1) 
				{
					case SM_BYTE:       // Byte
						m_wCaretPosX1=16/m_nLineGroup-1;
						m_wCaretPosX2=3;
						break;
					case SM_WORD:       // Word
						m_wCaretPosX1=8/m_nLineGroup-1;
						m_wCaretPosX2=5;
						break;
					case SM_DWORD:       // Long
						m_wCaretPosX1=4/m_nLineGroup-1;
						m_wCaretPosX2=10;
						break;
					default:
						break;
				}
				break;

			default:
				break;
		}
}

void CMemoryWindow::Tab()
{
	if (m_nCaretArea==2)
	{
		if(m_bViewMode1==SM_BYTE)
			m_wCaretPosX1=m_wCaretPosX2;
		else if(m_bViewMode1==SM_WORD)
			m_wCaretPosX1=m_wCaretPosX2/2;
		else
			m_wCaretPosX1=m_wCaretPosX2/4;
		m_wCaretPosX2=0;
		m_nCaretArea=1;
	}
	else
	{
		if(m_bViewMode1==SM_BYTE)
			m_wCaretPosX2=m_wCaretPosX1;
		else if(m_bViewMode1==SM_WORD)
			m_wCaretPosX2=m_wCaretPosX1*2;
		else
			m_wCaretPosX2=m_wCaretPosX1*4;
		m_nCaretArea=2;
	}
}

void CMemoryWindow::OnModeChange(void)
{
LPARAM	lParam;
WPARAM	type;            
RECT	rect;
	
	m_nPosX=0;
	GetClientRect(&rect);
	if (IsZoomed())
		type=SIZE_MAXIMIZED;
	else
		type=SIZE_RESTORED;
	if(IsIconic())
		type=SIZE_MINIMIZED;
	lParam = rect.bottom;
	lParam <<=16;
	lParam += rect.right;
	SendMessage(WM_SIZE,type,lParam);
	Invalidate();
}

//caller condition:
// 1. scroll vertically.
// 2. change memory region
// 3. window size change
// 4. refresh hard.
// 5. window create
void CMemoryWindow::PrepareData()
{
DWORD head, movelen;
DWORD end;
long  begAddr;

//	ASSERT((m_dwStartAddress+(m_nLines-2)*(0x10/m_nLineGroup)-1)<0x10000);
	ASSERT(m_dwStartAddress<0x10000);
	end=min(m_dwStartAddress+(m_nLines-2)*0x10-1, 0x10000-1);

	end=min(end, m_dwMemRegionEnd);
	if(m_dwStartAddress>=m_dwBufStartAddr&&end<=m_dwBufEndAddr)
		m_byMem=&m_pMemBuffer[m_dwStartAddress-m_dwBufStartAddr];
	else if(m_dwStartAddress<m_dwBufStartAddr&&end>=m_dwBufStartAddr&&
			end<=m_dwBufEndAddr)
	{
		//will use head part data in buffer.
		head=min(m_wMemBufferLen/3, m_dwStartAddress);
		movelen=head+m_dwBufStartAddr-m_dwStartAddress;
		if(m_wMemBufferLen-(m_dwBufEndAddr-m_dwBufStartAddr+1)>movelen)
		{
			ASSERT(m_dwBufEndAddr-m_dwBufStartAddr+1<0x8000);
			memmove(&m_pMemBuffer[movelen], m_pMemBuffer, 
					int(m_dwBufEndAddr-m_dwBufStartAddr+1));
		}
		else    //lost useful data in tail:
		{
			ASSERT(m_wMemBufferLen-movelen<0x8000);
			memmove(&m_pMemBuffer[movelen], m_pMemBuffer,
					int(m_wMemBufferLen-movelen));
			m_dwBufEndAddr=min(m_dwBufEndAddr,
					m_dwBufStartAddr+(m_wMemBufferLen-movelen)-1);
		}
		ASSERT(m_dwBufEndAddr>=end);
		begAddr=m_dwBufStartAddr-movelen;
		MyMemServerDump(m_pMemBuffer, long(begAddr), long(movelen), m_nSpaceType);
		m_dwBufStartAddr-=movelen;
		m_byMem=&m_pMemBuffer[head];
	}
	else if(m_dwStartAddress>=m_dwBufStartAddr&&m_dwStartAddress<=m_dwBufEndAddr
			&&end>m_dwBufEndAddr)
	{
		//will use tail part data in buffer.
		if(end<m_dwBufStartAddr+m_wMemBufferLen-1)	//not need move buffer
		{
			movelen=min(m_wMemBufferLen-m_dwBufEndAddr+
						m_dwBufStartAddr-1, m_dwMemRegionEnd-m_dwBufEndAddr);
			begAddr=m_dwBufEndAddr+1;
			MyMemServerDump(&m_pMemBuffer[m_dwBufEndAddr-m_dwBufStartAddr+1], 
					(long)begAddr, long(movelen), m_nSpaceType);
			m_dwBufEndAddr+=movelen;
			m_byMem=&m_pMemBuffer[m_dwStartAddress-m_dwBufStartAddr];
		}
		else
		{
			ASSERT(m_dwStartAddress-m_dwBufStartAddr>m_wMemBufferLen/3);
			head=m_dwStartAddress-m_dwBufStartAddr-m_wMemBufferLen/3;
			ASSERT(m_dwBufEndAddr-m_dwBufStartAddr+1-head<0X8000);
			memmove(m_pMemBuffer, &m_pMemBuffer[head],
					int(m_dwBufEndAddr-m_dwBufStartAddr+1-head));
			m_dwBufStartAddr+=head;
			movelen=min(m_wMemBufferLen-(m_dwBufEndAddr-m_dwBufStartAddr+1),
						m_dwMemRegionEnd-m_dwBufEndAddr);
			begAddr=m_dwBufEndAddr+1;
			MyMemServerDump(&m_pMemBuffer[m_dwBufEndAddr-m_dwBufStartAddr+1], 
						(long)begAddr, long(movelen), m_nSpaceType);
			m_dwBufEndAddr+=movelen;
			m_byMem=&m_pMemBuffer[m_dwStartAddress-m_dwBufStartAddr];
		}
	}
	else
	{
		m_dwBufStartAddr=m_dwStartAddress>m_wMemBufferLen/3?
					m_dwStartAddress-m_wMemBufferLen/3:0;
		movelen=m_dwBufStartAddr+m_wMemBufferLen-1>m_dwMemRegionEnd?
				m_dwMemRegionEnd-m_dwBufStartAddr+1:m_wMemBufferLen;
		begAddr=m_dwBufStartAddr;
		ASSERT(movelen<0x10000);
		MyMemServerDump(m_pMemBuffer, (long)begAddr, (long)movelen, m_nSpaceType);
		m_dwBufEndAddr=m_dwBufStartAddr+movelen-1;
		m_byMem=&m_pMemBuffer[m_dwStartAddress-m_dwBufStartAddr];
	}
	if(m_bViewMode2==SM_CODE)
	{
		m_nDSMNum=m_nLines-2;
		ASSERT(m_nDSMNum>=0&&m_wDSMBufferLen>=(WORD)m_nDSMNum);
		GetDsm(m_nSpaceType, m_dwStartAddress, m_nDSMNum, (DADMEMSTRU*)m_dsm, m_nSpaceType);
		m_dwBottomlineAddr=m_dsm[m_nDSMNum-1].address;
	}
	if(m_dwBufEndAddr-m_dwBufStartAddr+1>m_wMemBufferLen)
		ASSERT(0);
	return;
}

BOOL CMemoryWindow::InputCheck(UINT nChar)
{
BOOL bOk;

	bOk = FALSE;

	if(m_nCaretArea==2)
	{
		if(isprint(nChar))
			bOk=TRUE;
		if(bOk)
			GetValue();
	}
	else
	{
		switch(m_bViewMode2) 
		{
			case SM_CODE:
				break;
			case SM_HEX:
				if (('0'<=nChar)&&(nChar<='9'))
					bOk=TRUE;
				if (('a'<=nChar)&&(nChar<='f'))
					bOk=TRUE;
				if (('A'<=nChar)&&(nChar<='F'))
					bOk=TRUE;
				if (bOk)
				{
					GetValue();
					ValueToStr();
					m_lpszValue[m_wCaretPosX2]=(char)nChar;
					bOk = StrToValue();
				}
				break;
			case SM_UDEC:
				if (('0'<=nChar)&&(nChar<='9'))
					bOk=TRUE;
				if (bOk) 
				{
					GetValue();
					ValueToStr();
					m_lpszValue[m_wCaretPosX2]=(char)nChar;
					bOk = StrToValue();
				}
				break;
			case SM_DEC:
				if (m_wCaretPosX2==0)
				{
					if (('+'==nChar)||((nChar=='-')&&(m_bViewMode1!=1)))
						bOk=TRUE;
				}
				else if (('0'<=nChar)&&(nChar<='9')) bOk=TRUE;
				if (bOk)
				{
					GetValue();
					ValueToStr();
					m_lpszValue[m_wCaretPosX2]=(char)nChar;
					bOk = StrToValue();
				}
				break;
			default:
				break;
		}
	}
	if (!bOk) 
		MessageBeep(-1);
	return bOk;
}

void CMemoryWindow::WriteMemory(UINT nChar)
{
long* l;
WORD* w;
BYTE* b;
BYTE value;
UINT i;
long addr;
BYTE* f;
long begAddr;

	b = (BYTE *)m_byMem;
	w = (WORD *)m_byMem;
	l = (long *)m_byMem;
	i = m_wCaretPosY - (UINT)(m_dwStartAddress/(16/m_nLineGroup));

	if (m_nCaretArea==2)
	{
		b = b + i*(16/m_nLineGroup) + m_wCaretPosX2;

		addr = m_wCaretPosY*(16/m_nLineGroup) + m_wCaretPosX2;
		value = (BYTE)nChar;
		begAddr=addr;
		MemServerFill(begAddr, value, m_nSpaceType);
		MyMemServerDump(&value, begAddr, 1, m_nSpaceType);
		*b = value;
	}
	else
	{
		switch(m_bViewMode1)
		{
		case SM_DWORD:
			l = l + i*(4/m_nLineGroup) + m_wCaretPosX1;
			f = (BYTE *)(&m_lValue);
			addr = m_wCaretPosY*(16/m_nLineGroup) + m_wCaretPosX1*4;
            begAddr=addr;
			MemServerFill(begAddr,*f, m_nSpaceType);
			MyMemServerDump(&value,begAddr,1, m_nSpaceType);
			*f = value;

			f++;
			addr++;
			begAddr++;
			MemServerFill(begAddr,*f, m_nSpaceType);
			MyMemServerDump(&value,begAddr,1, m_nSpaceType);
			*f = value;

			f++;
			addr++;
			begAddr++;
			MemServerFill(begAddr,*f, m_nSpaceType);
			MyMemServerDump(&value,begAddr,1, m_nSpaceType);
			*f = value;

			f++;
			addr++;
			begAddr++;
			MemServerFill(begAddr,*f, m_nSpaceType);
			MyMemServerDump(&value,begAddr,1, m_nSpaceType);
			*f = value;

			*l = m_lValue;
			break;

		case SM_WORD:
			w = w + i*(8/m_nLineGroup) + m_wCaretPosX1;
			f = (BYTE *)(&m_wValue);
			addr = m_wCaretPosY*(16/m_nLineGroup) + m_wCaretPosX1*2;
            begAddr=addr;
			MemServerFill(begAddr,*f, m_nSpaceType);
			MyMemServerDump(&value,begAddr,1, m_nSpaceType);
			*f = value;

			f++;
			addr++;
			begAddr++;
			MemServerFill(begAddr,*f, m_nSpaceType);
			MyMemServerDump(&value,begAddr,1, m_nSpaceType);
			*f = value;

			*w = m_wValue;
			break;

		case SM_BYTE:
			b = b + i*(16/m_nLineGroup) + m_wCaretPosX1;

			f = &m_byValue;
			addr = m_wCaretPosY*(16/m_nLineGroup) + m_wCaretPosX1;
            begAddr=addr;
			MemServerFill(begAddr,*f, m_nSpaceType);
			MyMemServerDump(&value,begAddr,1, m_nSpaceType);
			*f = value;

			*b = m_byValue;
			break;

		default:
			break;
		}
	}
}

void CMemoryWindow::GetValue()
{
long* l;
WORD* w;
BYTE* b;
int j,pos;
BYTE value;
UINT i;

    b = (BYTE *)m_byMem;
    w = (WORD *)m_byMem;
    l = (long *)m_byMem;
    
    i = m_wCaretPosY - (UINT)(m_dwStartAddress/(16/m_nLineGroup));

    if (m_nCaretArea==2) {
        b = b + i*(16/m_nLineGroup);
        for(j=0;j<(16/m_nLineGroup);j++) {
            pos = j;
            value = b[pos];
            if ((0x20<value)&&(value<=0x7e)) m_lpszValue[j]=value;
            else m_lpszValue[j]='.';
        }
        m_lpszValue[j]='\0';
    }
    else {
        switch(m_bViewMode1) {
            case 3:
                l = l + i*(4/m_nLineGroup) + m_wCaretPosX1;
                m_lValue = *l;
                break;
            case 2:
                w = w + i*(8/m_nLineGroup) + m_wCaretPosX1;
                m_wValue = *w;
                break;
            case 1:
                b = b + i*(16/m_nLineGroup) + m_wCaretPosX1;
                m_byValue = *b;
                break;
            default:
                break;
        }
    }
}

void CMemoryWindow::ValueToStr()
{
    switch (m_bViewMode2) {
        case 3:
            switch(m_bViewMode1) {
                case 3:
                    sprintf(m_lpszValue,"%08lX",m_lValue);
                    break;
                case 2:
                    sprintf(m_lpszValue,"%04X",m_wValue);
                    break;
                case 1:
                    sprintf(m_lpszValue,"%02X",m_byValue);
                    break;
                default:
                    break;
            }
            break;
        case 2:
            switch(m_bViewMode1) {
                case 3:
                    sprintf(m_lpszValue,"%010lu",m_lValue);
                    break;
                case 2:
                    sprintf(m_lpszValue,"%05u",m_wValue);
                    break;
                case 1:
                    sprintf(m_lpszValue,"%03u",m_byValue);
                    break;
                default:
                    break;
            }
            break;
        case 1:
            switch(m_bViewMode1) {
                case 3:
                    sprintf(m_lpszValue,"%+011ld",m_lValue);
                    break;
                case 2:
                    sprintf(m_lpszValue,"%+06d",m_wValue);
                    break;
                case 1:
                    sprintf(m_lpszValue,"%+04d",m_byValue);
                    break;
                default:
                    break;
            }
            break;
        default:
            break;
    }
}

BOOL CMemoryWindow::StrToValue()
{
long value;
BOOL bOk;

    bOk=TRUE;
    switch (m_bViewMode2) {
        case 3:
            switch(m_bViewMode1) {
                case 3:
                    value=strtoul(m_lpszValue,NULL,16);
                    m_lValue = value;
                    break;
                case 2:
                    value=strtol(m_lpszValue,NULL,16);
                    m_wValue = (WORD)value;
                    break;
                case 1:
                    value=strtol(m_lpszValue,NULL,16);
                    m_byValue = (BYTE)value;
                    break;
                default:
                    break;
            }
            break;
        case 2:
            switch(m_bViewMode1) {
                case 3:
                    value=strtoul(m_lpszValue,NULL,10);
                    if (errno==ERANGE) bOk = FALSE;
                    else bOk=TRUE;
                    errno=0;
                    m_lValue = value;
                    break;
                case 2:
                    value=strtol(m_lpszValue,NULL,10);
                    if ((value>=0)&&(value<=0xffff)) bOk = TRUE;
                    else bOk=FALSE;
                    m_wValue = (WORD)value;
                    break;
                case 1:
                    value=strtol(m_lpszValue,NULL,10);
                    if ((value>=0)&&(value<=0xff)) bOk = TRUE;
                    else bOk=FALSE;
                    m_byValue = (BYTE)value;
                    break;
                default:
                    break;
            }
            break;
            
        case 1:
            switch(m_bViewMode1) {
                case 3:
                    value=strtol(m_lpszValue,NULL,10);
                    if (errno==ERANGE) bOk = FALSE;
                    else bOk=TRUE;
                    errno=0;
                    m_lValue = value;
                    break;
                case 2:
                    value=strtol(m_lpszValue,NULL,10);
                    if ((value>=(long)(-32768))&&(value<=0x7fff)) bOk = TRUE;
                    else bOk=FALSE;
                    m_wValue = (WORD)value;
                    break;
                case 1:
                    value=strtol(m_lpszValue,NULL,10);
                    if ((value>=0)&&(value<=0xff)) bOk = TRUE;
                    else bOk=FALSE;
                    m_byValue = (BYTE)value;
                    break;
                default:
                    break;
            }
            break;
        default:
            break;
    }
    
    return bOk;
}

void CMemoryWindow::SetRegionEnd(void)
{
	switch(m_nSpaceType)
	{
		case 1:
		case 6:
		case 7:
		case 8:
		case 9:
			m_dwMemRegionEnd=pMax;
			break;
		case 2:
			m_dwMemRegionEnd=xMax;
			break;
		case 3:
			m_dwMemRegionEnd=iMax;
			break;
		default:
			ASSERT(0);
			break;
	}
}

/////////////////////////////////////////////////////////////////////////////
// CMemoryWindow message handlers
//

int CMemoryWindow::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

TEXTMETRIC tm;
CDC* pdc=GetDC();

	pdc->SelectStockObject(ANSI_FIXED_FONT);
	pdc->GetTextMetrics(&tm);
	m_nCharWidth=tm.tmAveCharWidth;
	m_nLineHeight=tm.tmHeight+tm.tmExternalLeading+2;
	ReleaseDC(pdc);

	PrepareData();
	SetWindowTitle();
	m_gridAddr.SetGridHeight(m_nLineHeight);
	SetFocus();      // Add on 1996.4.12
	return 0;
}

void CMemoryWindow::OnPaint()
{
static int dbCount=0;
	CPaintDC dc(this); // device context for painting

//	TRACE("call OnPaint %d time, m_dwStartAddress is %04x.\n", dbCount++,
//		m_dwStartAddress);
	// TODO: Add your message handler code here
	m_gridMem.Show(&dc,TRUE);
	if (m_bViewMode2!=SM_CODE)
	{
		if (m_bShowAscii)
			m_gridAscii.Show(&dc,TRUE);
	}
	else
		m_gridInstruction.Show(&dc, 2);
	m_gridAddr.Show(&dc,TRUE);	
	
	dc.SelectStockObject(ANSI_FIXED_FONT);
	ShowMemoryWindow(&dc);
	SetMyCaretPos();
//	SetScrollPos(SB_VERT, (UINT)(m_dwStartAddress/0x10), TRUE);

	// Do not call CMDIChildWnd::OnPaint() for painting messages
}

void CMemoryWindow::OnRButtonDown(UINT nFlags, CPoint point)
{
    // TODO: Add your message handler code here and/or call default
    CMenu * pLocalMenu = new CMenu;

    ASSERT(pLocalMenu!=NULL);
    pLocalMenu->CreatePopupMenu();
    
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_REFRESH, "&Refresh");
    pLocalMenu->AppendMenu(MF_SEPARATOR);
   
    pLocalMenu->AppendMenu(MF_STRING, ID_GROUP_MEMORY, "&Memory...");
    pLocalMenu->AppendMenu(MF_STRING, ID_MAP, "Ma&p...");
    pLocalMenu->AppendMenu(MF_STRING, ID_EDIT_GOTO, "&Goto...");
    pLocalMenu->AppendMenu(MF_SEPARATOR);
   
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_SHORTLINE, "Sh&ort line mode");
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_ASCII, "Show &ASCII");
    pLocalMenu->AppendMenu(MF_SEPARATOR);
   
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_HEXADECIMAL, "&Hexadecimal");
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_SIGNEDDECIMAL, "&Signed Decimal");
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_UNSIGNEDDECIMAL, "&Unsigned Decimal");
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_DISASSEMBLE, "&Disassemble");
    pLocalMenu->AppendMenu(MF_SEPARATOR);
   
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_BYTE, "&Byte");
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_WORD, "&Word");
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_LONG, "&Long");
       
    ClientToScreen(&point);
    pLocalMenu->TrackPopupMenu(TPM_CENTERALIGN, point.x, point.y, this);
    
    delete pLocalMenu;

    CMDIChildWnd::OnRButtonDown(nFlags, point);
}

BOOL CMemoryWindow::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
    // TODO: Add your message handler code here and/or call default
    if (message==WM_RBUTTONDOWN)
        return FALSE;

    return CMDIChildWnd::OnSetCursor(pWnd, nHitTest, message);
}

void CMemoryWindow::OnViewByte()
{
	// TODO: Add your command handler code here
	if (m_bViewMode1==SM_BYTE)
		return;
	m_bViewMode1 = SM_BYTE;
	
	switch (m_bWndNo) {
	  case 0:
	       sb_Mem1ViewMode1 =SM_BYTE;
	       break;
	  case 1:
	       sb_Mem2ViewMode1 =SM_BYTE;
	       break;
	  case 2:
	       sb_Mem3ViewMode1 =SM_BYTE;
	       break;
	}
	m_wCaretPosX1=0;
	m_wCaretPosX2=0;
	OnModeChange();
}

void CMemoryWindow::OnUpdateViewByte(CCmdUI* pCmdUI)
{
	// TODO: Add your command update UI handler code here
unsigned char uchCpuStatus;

	if(GetCpuStatus(uchCpuStatus))
	{
		if(1==uchCpuStatus)			// Is on GO status (STATUS_GO)
			pCmdUI->Enable(FALSE);
		else
			pCmdUI->Enable(TRUE);
	}
	if (m_bViewMode2 == SM_CODE)
		pCmdUI->Enable(FALSE);
	if (m_bViewMode1==SM_BYTE)
		pCmdUI->SetRadio(TRUE);
	else
		pCmdUI->SetRadio(FALSE);
}

void CMemoryWindow::OnViewWord()
{
    // TODO: Add your command handler code here
	if (m_bViewMode1==SM_WORD)
		return;
	m_bViewMode1=SM_WORD;
	switch (m_bWndNo)
	{
		case 0:
			sb_Mem1ViewMode1 = 2;
			break;
		case 1:
			sb_Mem2ViewMode1 = 2;
			break;
		case 2:
			sb_Mem2ViewMode1 = 2;
			break;
	}
	m_wCaretPosX1=0;
	m_wCaretPosX2=0;

	OnModeChange();
}

void CMemoryWindow::OnUpdateViewWord(CCmdUI* pCmdUI)
{
	// TODO: Add your command update UI handler code here
unsigned char uchCpuStatus;

	if (GetCpuStatus(uchCpuStatus))
	{
		if ( 1 == uchCpuStatus )			// Is on GO status (STATUS_GO)
			pCmdUI->Enable(FALSE);
		else          
			pCmdUI->Enable(TRUE);
	}
	if (m_bViewMode2 == SM_CODE)
		pCmdUI->Enable(FALSE);
	if (m_bViewMode1==SM_WORD)
		pCmdUI->SetRadio(TRUE);
	else
		pCmdUI->SetRadio(FALSE);
}

void CMemoryWindow::OnViewLong()
{
    // TODO: Add your command handler code here
	if (m_bViewMode1==SM_DWORD)
		return;
	m_bViewMode1=SM_DWORD;
	switch (m_bWndNo)
	{
		case 0:
			sb_Mem1ViewMode1 = 3;
			break;
		case 1:
			sb_Mem2ViewMode1 = 3;
			break;
		case 2:
			sb_Mem3ViewMode1 = 3;
			break;
	}
    m_wCaretPosX1=0;
    m_wCaretPosX2=0;

	OnModeChange();
}

void CMemoryWindow::OnUpdateViewLong(CCmdUI* pCmdUI)
{
	// TODO: Add your command update UI handler code here
unsigned char uchCpuStatus;

	if (GetCpuStatus(uchCpuStatus))
	{
		if ( 1 == uchCpuStatus )			// Is on GO status (STATUS_GO)
			pCmdUI->Enable(FALSE);
		else          
			pCmdUI->Enable(TRUE);
	}
	if (m_bViewMode2 == SM_CODE)
		pCmdUI->Enable(FALSE);
	if (m_bViewMode1==SM_DWORD)
		pCmdUI->SetRadio(TRUE);
	else
		pCmdUI->SetRadio(FALSE);
}

void CMemoryWindow::OnViewSigneddecimal()
{
	// TODO: Add your command handler code here
	if (m_bViewMode2==SM_DEC)
		return;
	m_dwStartAddress &=(long)0xFFF0+(m_nLineGroup==2?8:0);
	m_bViewMode2=SM_DEC;
	switch (m_bWndNo)
	{
		case 0:
			sb_Mem1ViewMode2 = SM_DEC;
			break;
		case 1:
			sb_Mem2ViewMode2 = SM_DEC;
			break;
		case 2:
			sb_Mem3ViewMode2 = SM_DEC;
			break;
	}
	m_wCaretPosX1=0;
	m_wCaretPosX2=0;
	OnModeChange();
}

void CMemoryWindow::OnUpdateViewSigneddecimal(CCmdUI* pCmdUI)
{
	// TODO: Add your command update UI handler code here
unsigned char uchCpuStatus;

	if (GetCpuStatus(uchCpuStatus))
	{
		if ( 1 == uchCpuStatus )			// Is on GO status (STATUS_GO)
			pCmdUI->Enable(FALSE);
		else
			pCmdUI->Enable(TRUE);
	}
	if (m_bViewMode2==SM_DEC)
		pCmdUI->SetRadio(TRUE);
	else
		pCmdUI->SetRadio(FALSE);
}

void CMemoryWindow::OnViewUnsigneddecimal()
{
	// TODO: Add your command handler code here
	if (m_bViewMode2==SM_UDEC)
		return;
	m_dwStartAddress &=(long)0xFFF0+(m_nLineGroup==2?8:0);
	m_bViewMode2=SM_UDEC;
	switch (m_bWndNo)
	{
		case 0:
			sb_Mem1ViewMode2 =SM_UDEC;
			break;
		case 1:
			sb_Mem2ViewMode2 =SM_UDEC;
			break;
		case 2:
			sb_Mem3ViewMode2 =SM_UDEC;
			break;
	}
	m_wCaretPosX1=0;
	m_wCaretPosX2=0;
	OnModeChange();
}

void CMemoryWindow::OnUpdateViewUnsigneddecimal(CCmdUI* pCmdUI)
{
	// TODO: Add your command update UI handler code here
unsigned char uchCpuStatus;

	if (GetCpuStatus(uchCpuStatus))
	{
		if ( 1 == uchCpuStatus )			// Is on GO status (STATUS_GO)
			pCmdUI->Enable(FALSE);
		else          
			pCmdUI->Enable(TRUE);
	}
	if (m_bViewMode2==SM_UDEC)
		pCmdUI->SetRadio(TRUE);
	else
		pCmdUI->SetRadio(FALSE);
}

void CMemoryWindow::OnViewHexadecimal()
{
    // TODO: Add your command handler code here
	if (m_bViewMode2==SM_HEX)
		return;
	m_dwStartAddress &=0xFFF0+(m_nLineGroup==2?8:0);
	m_bViewMode2=SM_HEX;
	switch (m_bWndNo)
	{
		case 0:
			sb_Mem1ViewMode2 = SM_HEX;
			break;
		case 1:
			sb_Mem2ViewMode2 = SM_HEX;
			break;
		case 2:
			sb_Mem3ViewMode2 = SM_HEX;
			break;
	}
	m_wCaretPosX1=0;
	m_wCaretPosX2=0;

	OnModeChange();
}

void CMemoryWindow::OnUpdateViewHexadecimal(CCmdUI* pCmdUI)
{
	// TODO: Add your command update UI handler code here
unsigned char uchCpuStatus;

	if (GetCpuStatus(uchCpuStatus))
	{
		if ( 1 == uchCpuStatus )			// Is on GO status (STATUS_GO)
			pCmdUI->Enable(FALSE);
		else          
			pCmdUI->Enable(TRUE);
	}

	if (m_bViewMode2==SM_HEX)
		pCmdUI->SetRadio(TRUE);
	else
		pCmdUI->SetRadio(FALSE);
}

void CMemoryWindow::OnViewDisassemble()
{
	// TODO: Add your command handler code here
	if (m_bViewMode2==SM_CODE)
		return;
	m_bViewMode2=SM_CODE;
	switch (m_bWndNo)
	{
		case 0:
			sb_Mem1ViewMode2 = SM_CODE;
			break;
		case 1:
			sb_Mem2ViewMode2 = SM_CODE;
			break;
		case 2:
			sb_Mem3ViewMode2 = SM_CODE;
			break;
	}

	OnModeChange();
}

void CMemoryWindow::OnUpdateViewDisassemble(CCmdUI* pCmdUI)
{
	// TODO: Add your command update UI handler code here
unsigned char uchCpuStatus;

	if (GetCpuStatus(uchCpuStatus))
	{
		if ( 1 == uchCpuStatus )			// Is on GO status (STATUS_GO)
			pCmdUI->Enable(FALSE);
		else
			pCmdUI->Enable(TRUE);
	}

	if (m_bViewMode2 == SM_CODE)
		pCmdUI->SetRadio(TRUE);
	else
		pCmdUI->SetRadio(FALSE);
}

void CMemoryWindow::OnViewShortline()
{
	// TODO: Add your command handler code here
	if (m_bViewMode2 == SM_CODE)
		return;
	m_nLineGroup=3-m_nLineGroup;
	m_dwStartAddress &=(long)0xFFF0+(m_nLineGroup==2?8:0);
	if(m_nLineGroup==1)			//from short line mode to normal mode
	{
		if(m_wCaretPosY%2)
		{
			if(m_nCaretArea==1)
				m_wCaretPosX1+=(m_bViewMode1==1?8:m_bViewMode1==2?4:2);
			else
				m_wCaretPosX2+=8;
		}
		m_wCaretPosY/=2;
	}
	else
	{
		m_wCaretPosY*=2;
		if(m_nCaretArea==2?m_wCaretPosX2>7:(m_bViewMode1==1?
			(m_wCaretPosX1>7):(m_bViewMode1==2?(m_wCaretPosX1>3):
			(m_wCaretPosX1>1))))
		{
			m_wCaretPosY+=1;
			if(m_nCaretArea==1)
				m_wCaretPosX1-=(m_bViewMode1==1?8:m_bViewMode1==2?4:2);
			else
				m_wCaretPosX2-=8;
		}
	}
	OnModeChange();
}

void CMemoryWindow::OnUpdateViewShortline(CCmdUI* pCmdUI)
{
	// TODO: Add your command update UI handler code here
unsigned char uchCpuStatus;

	if (GetCpuStatus(uchCpuStatus))
	{
		if ( 1 == uchCpuStatus )			// Is on GO status (STATUS_GO)
			pCmdUI->Enable(FALSE);
		else
			pCmdUI->Enable(TRUE);
	}
    if (m_bViewMode2 == SM_CODE)
    	pCmdUI->Enable(FALSE);
	if (m_nLineGroup==2)
		pCmdUI->SetCheck(TRUE);
	else
		pCmdUI->SetCheck(FALSE);
	
}

void CMemoryWindow::OnViewAscii()    
{
	// TODO: Add your command handler code here
	if (m_bViewMode2 == SM_CODE)
		return;
	m_bShowAscii = !m_bShowAscii;
	m_wCaretPosX1=0;
	m_wCaretPosX2=0;
	if (!m_bShowAscii)
		m_nCaretArea = 1;

	OnModeChange();
}

void CMemoryWindow::OnUpdateViewAscii(CCmdUI* pCmdUI)
{
	// TODO: Add your command update UI handler code here
	//pCmdUI->Enable(TRUE);
unsigned char uchCpuStatus;

	if (GetCpuStatus(uchCpuStatus))
	{
		if ( 1 == uchCpuStatus )			// Is on GO status (STATUS_GO)
			pCmdUI->Enable(FALSE);
		else
			pCmdUI->Enable(TRUE);
	}
    if (m_bViewMode2 == SM_CODE)
    	pCmdUI->Enable(FALSE);
	if (m_bShowAscii)
		pCmdUI->SetCheck(TRUE);
	else
		pCmdUI->SetCheck(FALSE);
}

void CMemoryWindow::OnSize(UINT nType, int cx, int cy)
{
static int dbcount=0;

int		lines = 0;
RECT	rect;
DWORD	wAddr = 0;

//	TRACE("OnSize called %d, cx: %d, cy: %d\n", 
//			dbcount++, cx, cy);
	CMDIChildWnd::OnSize(nType, cx, cy);
	m_bIconic=(nType==SIZE_MINIMIZED);
	if(m_bIconic)
		return;

	//set m_nLines
	lines=cy/m_gridAddr.m_nGridHeight+1;
	wAddr = m_dwStartAddress+(lines-2)*(0x10/m_nLineGroup);
	// Adjust the lines in views
	if(wAddr>m_dwMemRegionEnd+1)
	{
		if(m_dwMemRegionEnd+1<(lines-2)*(0x10/m_nLineGroup))
		{
			m_dwStartAddress=0;
			GetWindowRect(&rect);
			rect.bottom-=((lines-2-(m_dwMemRegionEnd+1)/
							(0x10/m_nLineGroup))*m_nLineHeight
							+cy%m_gridAddr.m_nGridHeight);
			SetWindowPos(NULL, rect.left,
						rect.top, 
						rect.right-rect.left,
						rect.bottom-rect.top,
						SWP_NOMOVE);
			return;
		}
		else
			m_dwStartAddress=m_dwMemRegionEnd+1-(lines-2)*(0x10/m_nLineGroup);
	}
	m_nLines = lines;
	SetMemoryWindow();		//depend on m_nLines and m_nPosX

	//set HScrollBar
	SetScrollBar();				//note: maybe cause WM_SIZE message.
	
	//set window height
	//int ret=(cy-2)%m_gridAddr.m_nGridHeight;	//mark by chris
	int ret=cy%m_gridAddr.m_nGridHeight;
	if(ret)
	{
		GetWindowRect(&rect);
		SetWindowPos(NULL,
					rect.left, rect.top,
					rect.right-rect.left,
					rect.bottom-rect.top-ret,
					SWP_NOMOVE);
		return;
	}

	//set VScrollBar
	ASSERT((m_dwMemRegionEnd+1)/(0x10/m_nLineGroup)-(m_nLines-2)+1<0x8000);
	int nScrollRange=int((m_dwMemRegionEnd+1)/(0x10/m_nLineGroup)-(m_nLines-2));
	SetScrollRange(SB_VERT, 0, nScrollRange, FALSE);
	ASSERT(m_dwStartAddress/(0x10/m_nLineGroup)<0x8000);
	SetScrollPos(SB_VERT, int(m_dwStartAddress/(0x10/m_nLineGroup)), TRUE);
	PrepareData();
}

void CMemoryWindow::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* /*pScrollBar*/)
{
     // TODO: Add your message handler code here and/or call default
long dwTempAddress = 0, dwTempAddress2 = 0;
unsigned char uchCpuStatus;
WORD oldv, line;
RECT rect;

	ASSERT(m_dwStartAddress<0x10000);
	oldv=WORD(m_dwStartAddress);
	if(!GetCpuStatus(uchCpuStatus))
	{
		return;
	}
	if (1==uchCpuStatus)		// CPU not at GO
	{
		ShowStatusGo();
		return;
	}
	switch (nSBCode)
	{
		case SB_LINEUP:
			if (m_dwStartAddress<=0)
				return;
			if(m_bViewMode2 != SM_CODE)
				m_dwStartAddress-=(0x10/m_nLineGroup);
			else
				m_dwStartAddress--;
			break;
		case SB_LINEDOWN:
			if (m_bViewMode2 != SM_CODE)
			{
				if(m_dwStartAddress+(m_nLines-2)*(0x10/m_nLineGroup)>m_dwMemRegionEnd)
					return;
				m_dwStartAddress += (0x10/m_nLineGroup);
			}
			else		//disassemble
			{
				if(m_dwBottomlineAddr>=m_dwMemRegionEnd)
					return;
				m_dwStartAddress++;
			}
			break;
		case SB_PAGEUP:
			if (m_bViewMode2!=SM_CODE)
			{
				ASSERT(m_nLines>=0);
				line=WORD(m_nLines>3?m_nLines-3:m_nLines);
				m_dwStartAddress=m_dwStartAddress>line*(0x10/m_nLineGroup)?
								 m_dwStartAddress-line*(0x10/m_nLineGroup):0;
			}
			else
				m_dwStartAddress=m_dwStartAddress>0x10?
								 m_dwStartAddress-0x10:0;
			break;
		case SB_PAGEDOWN:
			if (m_bViewMode2 != SM_CODE)
			{
				m_dwStartAddress=m_dwStartAddress+(m_nLines-3)*(0x10/m_nLineGroup);
				if(m_dwStartAddress+(m_nLines-2)*(0x10/m_nLineGroup)>m_dwMemRegionEnd)
					m_dwStartAddress=m_dwMemRegionEnd+1-(m_nLines-2)*(0x10/m_nLineGroup);
			}
			else
			{
				m_dwStartAddress = m_dwBottomlineAddr;
				if(m_dwStartAddress+m_nLines-2>m_dwMemRegionEnd)
					m_dwStartAddress=m_dwMemRegionEnd+1-(m_nLines-2);
			}   
			break;
		case SB_THUMBTRACK:
			SetWindowTitle(nPos*(0x10/m_nLineGroup));
			break;
		case SB_THUMBPOSITION:
			SetWindowTitle();
			m_dwStartAddress=(unsigned short)nPos*(0x10/m_nLineGroup);
			if (m_bViewMode2 != SM_CODE)
			{
				if(m_dwStartAddress+(m_nLines-2)*(0x10/m_nLineGroup)>m_dwMemRegionEnd)
					m_dwStartAddress=m_dwMemRegionEnd+1-(m_nLines-2)*(0x10/m_nLineGroup);
			}
			else
			{
				if((m_dwStartAddress+(m_nLines-2)*0x3-1)>m_dwMemRegionEnd)
					m_dwStartAddress=m_dwMemRegionEnd+1-(m_nLines-2)*3;
			}
//			EnableScrollBar( SB_VERT, ESB_DISABLE_BOTH );
//			EnableScrollBar( SB_VERT, ESB_ENABLE_BOTH );
			break;
		default:
			return;
	}
	if(oldv==m_dwStartAddress)
		return;
	PrepareData();
	ASSERT(m_dwStartAddress/(0x10/m_nLineGroup)<0x8000);
	SetScrollPos(SB_VERT, int(m_dwStartAddress/(0x10/m_nLineGroup)), TRUE);
	if(labs(oldv/(0x10/m_nLineGroup)-m_dwStartAddress/(0x10/m_nLineGroup))<m_nLines-2
		&&m_bViewMode2!=SM_CODE)
	{
		GetClientRect(&rect);
		rect.top = m_gridAddr.m_nGridHeight+1;
		ScrollWindow(0,	int(long(oldv/(0x10/m_nLineGroup))-long(m_dwStartAddress/(0x10/m_nLineGroup)))*
					 m_gridAddr.m_nGridHeight, &rect, &rect);
		UpdateWindow();
	}
	else 
		Invalidate();
//	SetMyCaretPos();
}

void CMemoryWindow::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* /*pScrollBar*/)
{
    // TODO: Add your message handler code here and/or call default
int nInt1,nInt2;
unsigned char uchCpuStatus;
int oldh=m_nPosX;
RECT	rect;

	if(!m_bHScrollOn)
		return;
	if(!GetCpuStatus(uchCpuStatus))
	{
		return;
	}
	if (1==uchCpuStatus)		// CPU not at GO
	{
		ShowStatusGo();
		return;
	}
	GetScrollRange(SB_HORZ,&nInt1,&nInt2);
	GetClientRect(&rect);
	
	switch (nSBCode)
	{
		case SB_LINEUP:
			if(m_nPosX>=0)
				return;
			if ((m_nPosX+m_gridMem.m_nGridWidth) > 0)
				m_nPosX = 0;
			else
			  m_nPosX += m_gridMem.m_nGridWidth;
			break;
		case SB_LINEDOWN:
			if((m_nPosX+nInt2)<=0)
				return;
			if ((m_nPosX+nInt2) < m_gridMem.m_nGridWidth)
			  m_nPosX = -nInt2;
			else
			  m_nPosX -= m_gridMem.m_nGridWidth;
			break;
		case SB_PAGEUP:
			if (m_nPosX >=0)
				return;
			if((m_nPosX+rect.right)>0)
				m_nPosX = 0;
			else
				m_nPosX += rect.right;
			break;
			                  
		case SB_PAGEDOWN:
			if((m_nPosX+nInt2)<=0)
				return;
			if((m_nPosX+nInt2)<rect.right)
				m_nPosX = -nInt2;
			else
				m_nPosX -= rect.right;
			break;
		case SB_THUMBTRACK:
			m_nPosX=-int(nPos);
			break;
		default:
			break;
	}
	if(oldh!=m_nPosX)
	{
		SetMemoryWindow();		//depend on m_nLines and m_nPosX
		GetClientRect(&rect);
		rect.left = m_gridAddr.m_nGridWidth+1;
		SetScrollPos(SB_HORZ, -m_nPosX, TRUE);
		ScrollWindow(m_nPosX-oldh, 0, &rect, &rect);
		UpdateWindow();
	}
}

void CMemoryWindow::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: Add your message handler code here and/or call default
    BOOL bOk;
    CRect rect;
    RECT rect2;
    int i,j;

    bOk = FALSE;

    if (m_bViewMode2!=4) {
        if (m_bShowAscii) {
            rect.left = m_gridAscii.GetLeftPos();
            rect.right = m_gridAscii.GetRightPos();
            rect.top = m_gridAscii.m_rectPos.top+m_gridAscii.m_nGridHeight;
            rect.bottom = m_gridAscii.m_rectPos.bottom;
            bOk = rect.PtInRect(point);
            if (bOk) m_nCaretArea = 2;
            if (bOk) {
                i = point.x - m_gridAscii.GetLeftPos();
                if (i>1) i--;
                m_wCaretPosX1 = 0;
                m_wCaretPosX2 = WORD((i+m_nCharWidth/2-1) / m_nCharWidth);
                if (m_wCaretPosX2>WORD(16/m_nLineGroup-1))
                	m_wCaretPosX2 = (16/m_nLineGroup-1);
                i = point.y - rect.top;
                m_wCaretPosY =WORD(i / m_gridAscii.m_nGridHeight + 
                	(UINT)(m_dwStartAddress/(16/m_nLineGroup)));
            }
        }
        if (!bOk) {
            rect.left = m_gridAddr.m_nGridWidth;
            rect.right = m_gridMem.GetRightPos();
            rect.top = m_gridMem.m_rectPos.top+m_gridMem.m_nGridHeight;
            rect.bottom = m_gridMem.m_rectPos.bottom;
            bOk = rect.PtInRect(point);
            if (bOk) m_nCaretArea = 1;
            if (bOk) {
                i = point.y - rect.top;
                m_wCaretPosY =WORD(i / m_gridMem.m_nGridHeight +
                	(UINT)(m_dwStartAddress/(16/m_nLineGroup)));
                for(j=0;j<m_gridMem.m_nRows;j++) {
                    rect2 = m_gridMem.GetGridRect(j,(i/m_gridMem.m_nGridHeight+1));
                    rect.CopyRect(&rect2);
                    bOk = rect.PtInRect(point);
                    if (bOk) break;
                }

                i = point.x - rect.left;
                m_wCaretPosX1 = WORD(j);
                if (i>1) i--;
                m_wCaretPosX2 =WORD((i+m_nCharWidth/2-1) / m_nCharWidth);
                switch (m_bViewMode2) {
                    case 1:
                        switch (m_bViewMode1) {
                            case 1:
                                if (m_wCaretPosX2>3) m_wCaretPosX2 = 3;
                                break;
                            case 2:
                                if (m_wCaretPosX2>5) m_wCaretPosX2 = 5;
                                break;
                            case 3:
                                if (m_wCaretPosX2>10) m_wCaretPosX2 = 10;
                                break;
                            default:
                                break;
                        }
                        break;
                    case 2:
                        switch (m_bViewMode1) {
                            case 1:
                                if (m_wCaretPosX2>2) m_wCaretPosX2 = 2;
                                break;
                            case 2:
                                if (m_wCaretPosX2>4) m_wCaretPosX2 = 4;
                                break;
                            case 3:
                                if (m_wCaretPosX2>9) m_wCaretPosX2 = 9;
                                break;
                            default:
                                break;
                        }
                        break;
                    case 3:
                        switch (m_bViewMode1) {
                            case 1:
                                if (m_wCaretPosX2>1) m_wCaretPosX2 = 1;
                                break;
                            case 2:
                                if (m_wCaretPosX2>3) m_wCaretPosX2 = 3;
                                break;
                            case 3:
                                if (m_wCaretPosX2>7) m_wCaretPosX2 = 7;
                                break;
                            default:
                                break;
                        }
                        break;
                    default:
                        break;
                }
            }
        }
    }
    if (bOk) {
        SetMyCaretPos();
    }

    CMDIChildWnd::OnLButtonDown(nFlags, point);
}

void CMemoryWindow::OnMouseMove(UINT nFlags, CPoint point)
{
    // TODO: Add your message handler code here and/or call default
    CRect rect1;
    BOOL bOk;

    bOk = FALSE;
    if (m_bViewMode2!=4) {
        rect1.left = m_gridAddr.m_nGridWidth;
        rect1.right = m_gridMem.GetRightPos();
        rect1.top = m_gridMem.m_rectPos.top+m_gridMem.m_nGridHeight;
        rect1.bottom = m_gridMem.m_rectPos.bottom;
        if (m_bShowAscii) {
            rect1.right = m_gridAscii.GetRightPos();
            rect1.bottom = m_gridAscii.m_rectPos.bottom;
        }
        bOk = rect1.PtInRect(point);
    }
    if (bOk)
       SetCursor(::LoadCursor(NULL,IDC_IBEAM));
    else
       SetCursor(::LoadCursor(NULL,IDC_ARROW));

    CMDIChildWnd::OnMouseMove(nFlags, point);
}

void CMemoryWindow::OnKeyDown(UINT nChar, UINT /*nRepCnt*/, UINT /*nFlags*/)
{
    // TODO: Add your message handler code here and/or call default
DWORD dwTemp;
BOOL Up_Flag = 1;
BOOL Down_Flag = 1;
long dwTempAddress2 = 0;
unsigned char uchCpuStatus;
int	minpos, maxpos;
int bCtrl = GetKeyState(VK_CONTROL)&0x8000;
//int bShift= GetKeyState(VK_SHIFT) & 0x8000;

	if(m_bIconic)
		return;
	if(!GetCpuStatus(uchCpuStatus))
	{
		return;
	}
	if ( 1 == uchCpuStatus )			// CPU not at GO
	{
		ShowStatusGo();
		return;
	}
	if(m_bViewMode2 ==SM_CODE)
	{
		switch(nChar)
		{
			case VK_RIGHT:
				OnHScroll(SB_LINERIGHT, 0, NULL);
				break;
			case VK_LEFT:
				OnHScroll(SB_LINELEFT, 0, NULL);
				break;
			case VK_UP:
				OnVScroll(SB_LINEUP, 0, NULL);
				break;
			case VK_DOWN:
				OnVScroll(SB_LINEDOWN, 0, NULL);
				break;
			case VK_PRIOR:
				if(bCtrl)
					OnHScroll(SB_PAGEUP, 0, NULL);
				else
					OnVScroll(SB_PAGEUP, 0, NULL);
				break;
			case VK_NEXT:
				if(bCtrl)
					OnHScroll(SB_PAGEDOWN, 0, NULL);
				else
					OnVScroll(SB_PAGEDOWN, 0, NULL);
				break;
			case VK_HOME:
				if(bCtrl)
					OnVScroll(SB_THUMBPOSITION, 0, NULL);
				OnHScroll(SB_THUMBTRACK, 0, NULL);
				break;
			case VK_END:
				GetScrollRange(SB_HORZ, &minpos, &maxpos);
				if(bCtrl)
				{
					GetScrollRange(SB_VERT, &minpos, &maxpos);
					OnVScroll(SB_THUMBPOSITION, maxpos, NULL);
					break;
				}
				if(maxpos)
					OnHScroll(SB_THUMBTRACK, maxpos, NULL);
				break;
			default:
				break;
		}
		return;
	}
	switch (nChar) 
	{
		case VK_RIGHT:
			Right();
			break;
		case VK_LEFT:
			Left();
			break;
		case VK_UP:
			Up();
			break;
		case VK_DOWN:
			Down();
			break;
		case VK_PRIOR:
			dwTemp = m_dwStartAddress;
			if(InWnd())
			{	
				OnVScroll(SB_PAGEUP, 0, NULL);
				ASSERT((dwTemp-m_dwStartAddress)/(16/m_nLineGroup)<0X10000);
				m_wCaretPosY-=WORD((dwTemp-m_dwStartAddress)/(16/m_nLineGroup));
			}
			else
				m_wCaretPosY-=WORD(m_nLines>3?m_nLines-3:m_nLines);
			if(m_wCaretPosY<0)
				m_wCaretPosY=0;
			break;         
		case VK_NEXT:
			dwTemp = m_dwStartAddress;
			if(InWnd())
			{	
				OnVScroll(SB_PAGEDOWN, 0, NULL);
				ASSERT((m_dwStartAddress-dwTemp)/(16/m_nLineGroup)<0X10000);
				m_wCaretPosY+=WORD((m_dwStartAddress-dwTemp)/(16/m_nLineGroup));
			}
			else
			{
				m_wCaretPosY+=WORD(m_nLines>3?m_nLines-3:m_nLines);
				if(m_wCaretPosY+m_nLines-2>m_dwMemRegionEnd/(16/m_nLineGroup))
				{
					ASSERT(m_dwMemRegionEnd/(16/m_nLineGroup)-m_nLines+2<0x10000);
					m_wCaretPosY=WORD(m_dwMemRegionEnd/(16/m_nLineGroup)-m_nLines+2);
				}
			}
			ASSERT(m_wCaretPosY<=m_dwMemRegionEnd/(16/m_nLineGroup));
			break;         
		case VK_HOME:
			Home();
			break;
		case VK_END:
			End();
			break;
		case VK_TAB:
			Tab();
			break;
		default:
			break;
	}
	if (!InWnd())
		GotoCursor();
	xGotoCursor();
	SetMyCaretPos();
}

void CMemoryWindow::OnStkTab()
{
	// TODO: Add your command handler code here
	OnKeyDown(VK_TAB, 1, 0);
}

void CMemoryWindow::OnChar(UINT nChar, UINT /*nRepCnt*/, UINT /*nFlags*/)
{
    // TODO: Add your message handler code here and/or call default
unsigned char uchCpuStatus;
    
	if(m_bIconic)
		return;
	if(!GetCpuStatus(uchCpuStatus))
	{
		return;
	}
	if(1==uchCpuStatus)			// CPU not at GO
	{
		ShowStatusGo();
		return;
	}
	if (m_bViewMode2==SM_CODE)
	{
		return;
	}
	if (nChar!=VK_TAB)
	{
		if (InputCheck(nChar)) 
		{
			WriteMemory(nChar);
			PaintLine(WORD(m_wCaretPosY-m_dwStartAddress/(0x10/m_nLineGroup)));
			Right();
			if (isMemOn[0]&&(m_bWndNo!=0))
			{
				((CMemoryWindow*)pMemWnd[0])->RefreshMemWin(TRUE);
			}
			if (isMemOn[1]&&(m_bWndNo!=1))
			{
				((CMemoryWindow*)pMemWnd[1])->RefreshMemWin(TRUE);
			}
			if (isMemOn[2]&&(m_bWndNo!=2))
			{
				((CMemoryWindow*)pMemWnd[2])->RefreshMemWin(TRUE);
			}
			if((m_nSpaceType==3)&&(isBMemOn))
			{
				pBMemWnd->SendMessage(WM_COMMAND,ID_VIEW_REFRESH);
			}
			::RepaintStack();
			::RepaintVariable();
			// Added by Chen only for the stack window
			SetFocus();
		}
	}   
}

void CMemoryWindow::OnGroupMemory()
{
	// TODO: Add your command handler code here
	BOOL focus;

	focus = m_bFocus;
	m_bFocus = FALSE;
	CMemDlg dlg(NULL);
	dlg.DoModal();
	if (focus) m_bFocus = TRUE;
	RefreshMemWin(TRUE);
}

void CMemoryWindow::OnUpdateGroupMemory(CCmdUI* pCmdUI)
{
   // TODO: Add your command update UI handler code here
   unsigned char uchCpuStatus;
    
   if (GetCpuStatus(uchCpuStatus)) {
     if ( 1 == uchCpuStatus ) {       // Is on GO status (STATUS_GO)
        pCmdUI->Enable(FALSE);
     }
     else {
      pCmdUI->Enable(TRUE);
     }      
   }
}

void CMemoryWindow::OnMap()
{
    // TODO: Add your command handler code here
    // Open Map dialog.
    HINSTANCE hLib;
    if ( (hLib = LoadLibrary("MUSCROLL.DLL")) < HINSTANCE_ERROR ) {
        AfxMessageBox("MUSCROLL.DLL loading error.");
        // ::ErrGetErrorText(....);
        return;
    }
    
    CMapDlg dlg;
    dlg.DoModal();
    
    if ( hLib >= HINSTANCE_ERROR ) FreeLibrary(hLib);
}

void CMemoryWindow::OnUpdateMap(CCmdUI* pCmdUI)
{
   // TODO: Add your command update UI handler code here
   unsigned char uchCpuStatus;
    
   if (GetCpuStatus(uchCpuStatus)) {
     if ( 1 == uchCpuStatus ) {       // Is on GO status (STATUS_GO)
        pCmdUI->Enable(FALSE);
     }
     else {
      pCmdUI->Enable(TRUE);
     }      
   }
}

long CMemoryWindow::OnXMRepaint(UINT /*wParam*/,LONG /*lParam*/)
{
	RefreshMemWin(TRUE);
	return 0;
}

void CMemoryWindow::OnSetFocus(CWnd* pOldWnd)
{
	CMDIChildWnd::OnSetFocus(pOldWnd);

	// TODO: Add your message handler code here
	m_bFocus = TRUE;
	CreateSolidCaret(2, m_nLineHeight-2);
//	if (!InWnd())
//		GotoCursor();
	SetMyCaretPos();
}

void CMemoryWindow::OnKillFocus(CWnd* pNewWnd)
{
	CMDIChildWnd::OnKillFocus(pNewWnd);

	// TODO: Add your message handler code here
	m_bFocus = FALSE;
	DestroyCaret();
}

void CMemoryWindow::OnEditGoto()
{
    // TODO: Add your command handler code here
CMemGtDlg* pMemGtDlg;
BOOL	bSizeMsg=FALSE;

	if (IsIconic())
		ShowWindow( SW_RESTORE );

	if(sb_GotoSpace1==0xff)
		sb_GotoSpace1=m_nSpaceType;

	pMemGtDlg=new CMemGtDlg(this, m_bViewMode2==4);
	pMemGtDlg->m_nSpace=sb_GotoSpace1;
	pMemGtDlg->m_lAddress=sdw_GotoAddr1;
	if(IDOK==pMemGtDlg->DoModal())
	{
		sb_GotoSpace1=pMemGtDlg->m_nSpace;
		sdw_GotoAddr1=pMemGtDlg->m_lAddress;
		if(m_nSpaceType!=sb_GotoSpace1)
		{
			if(m_nSpaceType==3&&IsZoomed())			//onchip data
				bSizeMsg=TRUE;
			m_nSpaceType=sb_GotoSpace1;
			SetRegionEnd();
			//reset buffer content:
			m_dwBufStartAddr=0xffff;
			m_dwBufEndAddr=0;
			SetWindowTitle();
		}
		m_dwStartAddress=sdw_GotoAddr1;
		if(m_bViewMode2!=SM_CODE)
			m_dwStartAddress&=0xfff0+(m_nLineGroup==2?8:0);
		else
		{
			if(m_dwStartAddress+(m_nLines-2)*0x3-1>m_dwMemRegionEnd)
				m_dwStartAddress=m_dwMemRegionEnd+1-(m_nLines-2)*0x3;
		}
		ASSERT(m_dwStartAddress/(0x10/m_nLineGroup)<0x10000);
		m_wCaretPosY=WORD(m_dwStartAddress/(0x10/m_nLineGroup));
		m_nCaretArea==1;
		switch(m_bViewMode1)
		{
			case 1:
				m_wCaretPosX1=sdw_GotoAddr1&0xf;
				m_wCaretPosX2=0;
				break;
			case 2:
				m_wCaretPosX1=(sdw_GotoAddr1&0xf)/2;
				m_wCaretPosX2=0;
				break;
			case 3:
				m_wCaretPosX1=(sdw_GotoAddr1&0xf)/4;
				m_wCaretPosX2=0;
				break;
			default:
				break;
		}
		OnModeChange();
		GotoCursor();
		Invalidate();
	}
	delete pMemGtDlg;
	if(bSizeMsg)
	{
		ShowWindow(SW_SHOWMAXIMIZED);
		return;
		LPARAM	lParam;
		RECT	rect;

		(AfxGetApp()->m_pMainWnd)->GetClientRect(&rect);
		lParam = rect.bottom;
		lParam-=(lParam%m_gridAddr.m_nGridHeight);
		lParam <<=16;
		lParam += rect.right;
		PostMessage(WM_SIZE, SIZE_MAXIMIZED, lParam);
	}
}

void CMemoryWindow::OnUpdateEditGoto(CCmdUI* pCmdUI)
{
	// TODO: Add your command update UI handler code here
	//pCmdUI->Enable(TRUE);
	unsigned char uchCpuStatus;
	if (m_bIconic)
	{
		pCmdUI->Enable(FALSE);
		return;
	}

	if (GetCpuStatus(uchCpuStatus))
	{
	  if ( 1 == uchCpuStatus ) {       // Is on GO status (STATUS_GO)
	    pCmdUI->Enable(FALSE);
	  }
	  else {
	    pCmdUI->Enable(TRUE);
	  }      
	}
	else
		pCmdUI->Enable(FALSE);
}

void CMemoryWindow::OnMDIActivate(BOOL bActivate, CWnd* pActivateWnd,
                               CWnd* pDeactivateWnd)
{
    CMDIChildWnd::OnMDIActivate(bActivate, pActivateWnd, pDeactivateWnd);

    // TODO: Add your message handler code here
    if(bActivate && pActivateWnd == this) {
        /*AfxGetApp()->m_pMainWnd*/
        GetMDIFrame()->SendMessage(XM_MDIACTIVE, WORD(bActivate),
            LONG(WID_MEMORY));
        //GotoCursor();
    }
    else if(!bActivate && !pActivateWnd)
        /*AfxGetApp()->m_pMainWnd*/
        GetMDIFrame()->SendMessage(XM_MDIACTIVE, WORD(bActivate));
}

void CMemoryWindow::OnLButtonDblClk(UINT nFlags, CPoint point)
{
        // TODO: Add your message handler code here and/or call default
        long address;
        long address2;
        int i;
        CRect rect1;
        CRect rect2;

        if (m_bViewMode2==4) {
                m_gridMem.DoRect();
                m_gridInstruction.DoRect();

                rect1.left = m_gridMem.m_rectPos.left+m_gridAddr.m_rectPos.right;
                rect1.top = m_gridMem.m_rectPos.top+m_gridMem.m_nGridHeight;
                rect1.right = m_gridMem.m_rectPos.right+m_gridAddr.m_rectPos.right;
                rect1.bottom = m_gridMem.m_rectPos.bottom;

                rect2.left = m_gridInstruction.m_rectPos.left+m_gridAddr.m_rectPos.right;
                rect2.top = m_gridInstruction.m_rectPos.top+m_gridInstruction.m_nGridHeight;
                rect2.right = m_gridInstruction.m_rectPos.right+m_gridAddr.m_rectPos.right;
                rect2.bottom = m_gridInstruction.m_rectPos.bottom;

                if (rect1.PtInRect(point)) {
                        for(i=1;i<m_nLines;i++) {
                                rect1 = m_gridMem.GetGridRect(0,i);
                                if (rect1.PtInRect(point)) {
                                        address = (unsigned short)m_dsm[i-1].address;
                                        break;
                                }
                        }
                        CDsmEdit1 dlg(this);
                        dlg.m_lAddress = address;
                        dlg.m_nSpaceType = m_nSpaceType;
                        address2 = m_dwStartAddress;
                        dlg.DoModal();
                        m_dwStartAddress = address2;
                        InvalidateRect(NULL,FALSE);
                        ::RepaintMemory();
                }
                else if (rect2.PtInRect(point)) {
                        for(i=1;i<m_nLines;i++) {
                                rect1 = m_gridInstruction.GetGridRect(0,i);
                                if (rect1.PtInRect(point)) {
                                        address = (unsigned short)m_dsm[i-1].address;
                                        break;
                                }
                        }
                        CDsmEdit2 dlg(this);
                        dlg.m_lAddress = address;
                        dlg.m_nSpaceType = m_nSpaceType;
                        address2 = m_dwStartAddress;
                        dlg.DoModal();
                        m_dwStartAddress = address2;
                        InvalidateRect(NULL,FALSE);
                        ::RepaintMemory();
                }
        }

        CMDIChildWnd::OnLButtonDblClk(nFlags, point);
}

void CMemoryWindow::RefreshMemWin(BOOL hard)
{
	if(hard)
	{
		m_dwBufStartAddr=0xffff;
		m_dwBufEndAddr=0;
		PrepareData();
	}
	SetWindowTitle();
	Invalidate();
}

void CMemoryWindow::OnViewRefresh()
{
     // TODO: Add your command handler code here
int bCtrl = GetKeyState(VK_CONTROL)&0x8000;

    RefreshMemWin(1);
}

void CMemoryWindow::OnUpdateViewRefresh(CCmdUI* pCmdUI)
{
    // TODO: Add your command update UI handler code here
    unsigned char uchCpuStatus;
    
    if (GetCpuStatus(uchCpuStatus)) {
      if ( 1 == uchCpuStatus ) {       // Is on GO status (STATUS_GO)
         pCmdUI->Enable(FALSE);
      }
      else {
       pCmdUI->Enable(TRUE);
      }      
    }
}

void CMemoryWindow::OnEditSearch()
{
    // TODO: Add your command handler code here
    CMemSearchDlg dlg(this);
    int i;

    dlg.m_nSpaceType = m_nSpaceType;
    dlg.m_StartAddress = (unsigned short)m_dwStartAddress;
    dlg.m_StartAddress += (unsigned short)(m_wCaretPosY-m_dwStartAddress/16)*16;
    if (m_nCaretArea==1) {
      switch(m_bViewMode1) {
        case 1:
            dlg.m_StartAddress += (unsigned short)m_wCaretPosX1;
            break;
            
        case 2:
            dlg.m_StartAddress += (unsigned short)m_wCaretPosX1*2;
            break;
            
        case 3:
            dlg.m_StartAddress += (unsigned short)m_wCaretPosX1*4;
            break;
            
        default:
            break;
      }
    }  
    if (m_nCaretArea==2) {
        dlg.m_StartAddress += (unsigned short)m_wCaretPosX2;
    }
    strcpy(dlg.m_str, m_searchStr);
    i = dlg.DoModal();
    if (i) {
        strcpy(m_searchStr, dlg.m_str);
        if (dlg.m_lFindAddress == -1) {
           MessageBox("Not Found!",NULL, MB_OK);
           return;
        }
        m_dwStartAddress = (dlg.m_lFindAddress&0xFFFFFFF0);
        LONG   dwTempAddress = 0;
        dwTempAddress = (m_dwStartAddress+(m_nLines-4)*16);
        switch( m_nSpaceType ) {
           case      1:
           case	6:
           case 7:
           case 8:
           case 9:
              // Add by Daniel Lin 
              if (dwTempAddress >= ((long)pMax&0xFFF0)) {
                  m_dwStartAddress = pMax-(m_nLines-3)*16;
                  m_dwStartAddress &= 0xFFF0;
              }
              break;
                       
           case      2:
              // Add by Daniel Lin 
              if (dwTempAddress > ((long)xMax&0xFFF0)) {
                  m_dwStartAddress = xMax-(m_nLines-3)*16;
                  m_dwStartAddress &= 0xFFF0;
              }
              break;
                       
           case      3:
              // Add by Daniel Lin 
              if (dwTempAddress > ((long)iMax&0xFFF0)) {
                  m_dwStartAddress = iMax-(m_nLines-3)*16;
                  m_dwStartAddress &= 0xFFF0;
              }
              break;
        }                          
        
        i = (int)(dlg.m_lFindAddress&0x0000000F);
        m_wCaretPosY = (UINT)(dlg.m_lFindAddress>>4);
        if (m_nCaretArea==1) {
          switch(m_bViewMode1) {
            case 1:
                m_wCaretPosX1=i;
                m_wCaretPosX2=0;
                break;
                
            case 2:
                m_wCaretPosX1=i/2;
                m_wCaretPosX2=0;
                break;
                
            case 3:
                m_wCaretPosX1=i/4;
                m_wCaretPosX2=0;
                break;
                
            default:
                break;
          }
        }  
        if (m_nCaretArea==2) {
           m_wCaretPosX2 = i;
        }
        RefreshMemWin(1);
        SetScrollPos(SB_VERT,(UINT)(m_dwStartAddress/0x10),TRUE);
    }
}

void CMemoryWindow::OnUpdateEditSearch(CCmdUI* pCmdUI)
{
     // TODO: Add your command update UI handler code here
     unsigned char uchCpuStatus;
     
     if (m_bViewMode2!=4)  {
       if (GetCpuStatus(uchCpuStatus)) {
         if ( 1 == uchCpuStatus ) {       // Is on GO status (STATUS_GO)
            pCmdUI->Enable(FALSE);
         }
         else {
          pCmdUI->Enable(TRUE);
         }      
       }
     }     
     else 
       pCmdUI->Enable(FALSE);
}

void CMemoryWindow::OnEditSearchnext()
{
        // TODO: Add your command handler code here
    int i;
    ADDRESS startAddress, endAddress, addr;
    long FindAddress;
    BOOL bFind;
    char *text;

    text = new char [200];
    ASSERT(NULL != text);
    i = strlen(m_searchStr);
    if (i<=0) {
       OnEditSearch();
    }
    else {
         BeginWaitCursor();
         startAddress.adrAddress = (unsigned short)m_dwStartAddress;
         startAddress.adrAddress += (unsigned short)(m_wCaretPosY-m_dwStartAddress/16)*16;
         if (m_nCaretArea==1)
         switch(m_bViewMode1) {
             case 1:
                 startAddress.adrAddress += (unsigned short)(m_wCaretPosX1+1);
                 break;
             case 2:
                 startAddress.adrAddress += (unsigned short)(m_wCaretPosX1*2+2);
                 break;
             case 3:
                 startAddress.adrAddress += (unsigned short)(m_wCaretPosX1*4+4);
                 break;
             default:
                 break;
         }
         if (m_nCaretArea==2) {
             startAddress.adrAddress += (unsigned short)(m_wCaretPosX2+1);
         }

         strcpy(text, m_searchStr+2);
         startAddress.adrSpace=(::ADDR_SPACE)m_nSpaceType;
         endAddress.adrSpace=(::ADDR_SPACE)m_nSpaceType;
         endAddress.adrAddress=0xffff;
         bFind = MemServerSearch(startAddress,endAddress,text,0,addr);
         EndWaitCursor();
         if (!bFind) {
             MessageBox("Not Found!",NULL, MB_OK);
             return;
         }
         else {
             FindAddress = addr.adrAddress;
             m_dwStartAddress = (unsigned short)(FindAddress&(long)0xFFFFFFF0);
             LONG   dwTempAddress = 0;
             dwTempAddress = (m_dwStartAddress+(m_nLines-2)*16);
             switch( m_nSpaceType ) {
               case      1:
               case 6:
               case 7:
               case 8:
               case 9:
                 // Add by Daniel Lin 
                 if (dwTempAddress >= ((long)pMax&0xFFF0)) {
                     m_dwStartAddress = pMax-(m_nLines-3)*16;
                     m_dwStartAddress &= 0xFFF0;
                 }
                 break;
                          
               case      2:
                 // Add by Daniel Lin 
                 if (dwTempAddress > ((long)xMax&0xFFF0)) {
                     m_dwStartAddress = xMax-(m_nLines-3)*16;
                     m_dwStartAddress &= 0xFFF0;
                 }
                 break;
                          
               case      3:
                 // Add by Daniel Lin 
                 if (dwTempAddress > ((long)iMax&0xFFF0)) {
                     m_dwStartAddress = iMax-(m_nLines-3)*16;
                     m_dwStartAddress &= 0xFFF0;
                 }
                 break;
             }                          
             
             i = (int)(FindAddress&(long)0x0000000F);
             m_wCaretPosY = (UINT)(/*m_dwStartAddress*/FindAddress>>4);
             if (m_nCaretArea==1)
             switch(m_bViewMode1) {
                 case 1:
                     m_wCaretPosX1=i;
                     m_wCaretPosX2=0;
                     break;
                     
                 case 2:
                     m_wCaretPosX1=i/2;
                     m_wCaretPosX2=0;
                     break;
                     
                 case 3:
                     m_wCaretPosX1=i/4;
                     m_wCaretPosX2=0;
                     break;
                     
                 default:
                     break;
             }
             if (m_nCaretArea==2) {
                     m_wCaretPosX2 = i;
             }
             RefreshMemWin(1);
             SetScrollPos(SB_VERT, (UINT)(m_dwStartAddress/0x10), TRUE);
        }
    }
    
    delete []text;
}

void CMemoryWindow::OnUpdateEditSearchnext(CCmdUI* pCmdUI)
{
  // TODO: Add your command update UI handler code here
  unsigned char uchCpuStatus;
  
  if (m_bViewMode2!=4) {
    if (GetCpuStatus(uchCpuStatus)) {
      if ( 1 == uchCpuStatus ) {       // Is on GO status (STATUS_GO)
         pCmdUI->Enable(FALSE);
      }
      else {
       pCmdUI->Enable(TRUE);
      }      
    }
  }  
  else pCmdUI->Enable(FALSE);
}

void CMemoryWindow::OnShiftreturn()
{
    // TODO: Add your command handler code here
    CMenu * pLocalMenu = new CMenu;

    ASSERT(pLocalMenu!=NULL);

    pLocalMenu->CreatePopupMenu();
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_REFRESH, "&Refresh");
    pLocalMenu->AppendMenu(MF_SEPARATOR);

    pLocalMenu->AppendMenu(MF_STRING, ID_GROUP_MEMORY, "&Memory...");
    pLocalMenu->AppendMenu(MF_STRING, ID_MAP, "Ma&p...");
    pLocalMenu->AppendMenu(MF_STRING, ID_EDIT_GOTO, "&Goto...");
    pLocalMenu->AppendMenu(MF_SEPARATOR);

    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_SHORTLINE, "Sh&ort line mode");
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_ASCII, "Show &ASCII");
    pLocalMenu->AppendMenu(MF_SEPARATOR);

    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_HEXADECIMAL, "&Hexadecimal");
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_SIGNEDDECIMAL, "&Signed Decimal");
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_UNSIGNEDDECIMAL, "&Unsigned Decimal");
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_DISASSEMBLE, "&Disassemble");
    pLocalMenu->AppendMenu(MF_SEPARATOR);

    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_BYTE, "&Byte");
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_WORD, "&Word");
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_LONG, "&Long");
    
    CPoint point(20, 20);
    ClientToScreen(&point);
    pLocalMenu->TrackPopupMenu(TPM_LEFTALIGN, point.x, point.y, this);
              
    delete pLocalMenu;
}

void CMemoryWindow::OnSysCommand(UINT nID, LPARAM lParam)
{
   // TODO: Add your message handler code here and/or call default
   unsigned char uchCpuStatus;
   
   if (GetCpuStatus(uchCpuStatus)) {
     if ( 1 == uchCpuStatus ) {       // Is on GO status (STATUS_GO)
      if ( SC_ZOOM == nID ) {
         ShowStatusGo();
         return;          // Zoomed
      }         
      if ( SC_MAXIMIZE == nID ) {
         ShowStatusGo();
         return;      // Zoomed
      }         
      if ( SC_RESTORE == nID ) {
         ShowStatusGo();
         return;       // Restore
      }         
      if ( SC_SIZE == nID ) {
         ShowStatusGo();
         return;       // Restore
      }         
      //if ( SC_MOVE == nID ) return;       // Restore      
     }
   }        
      
   CMDIChildWnd::OnSysCommand(nID, lParam);
}

BEGIN_MESSAGE_MAP(CMemoryWindow, CMDIChildWnd)
	//{{AFX_MSG_MAP(CMemoryWindow)
	ON_WM_CREATE()
	ON_WM_PAINT()
	ON_WM_RBUTTONDOWN()
	ON_WM_SETCURSOR()
	ON_COMMAND(ID_VIEW_BYTE, OnViewByte)
	ON_UPDATE_COMMAND_UI(ID_VIEW_BYTE, OnUpdateViewByte)
	ON_COMMAND(ID_VIEW_WORD, OnViewWord)
	ON_UPDATE_COMMAND_UI(ID_VIEW_WORD, OnUpdateViewWord)
	ON_COMMAND(ID_VIEW_LONG, OnViewLong)
	ON_UPDATE_COMMAND_UI(ID_VIEW_LONG, OnUpdateViewLong)
	ON_COMMAND(ID_VIEW_SIGNEDDECIMAL, OnViewSigneddecimal)
	ON_UPDATE_COMMAND_UI(ID_VIEW_SIGNEDDECIMAL, OnUpdateViewSigneddecimal)
	ON_COMMAND(ID_VIEW_HEXADECIMAL, OnViewHexadecimal)
	ON_UPDATE_COMMAND_UI(ID_VIEW_HEXADECIMAL, OnUpdateViewHexadecimal)
	ON_COMMAND(ID_VIEW_DISASSEMBLE, OnViewDisassemble)
	ON_UPDATE_COMMAND_UI(ID_VIEW_DISASSEMBLE, OnUpdateViewDisassemble)
	ON_COMMAND(ID_VIEW_ASCII, OnViewAscii)
	ON_UPDATE_COMMAND_UI(ID_VIEW_ASCII, OnUpdateViewAscii)
	ON_COMMAND(ID_VIEW_UNSIGNEDDECIMAL, OnViewUnsigneddecimal)
	ON_UPDATE_COMMAND_UI(ID_VIEW_UNSIGNEDDECIMAL, OnUpdateViewUnsigneddecimal)
	ON_WM_SIZE()
	ON_WM_VSCROLL()
	ON_WM_HSCROLL()
	ON_WM_SETFOCUS()
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_KEYDOWN()
	ON_WM_CHAR()
	ON_MESSAGE(XM_REPAINT,OnXMRepaint)
	ON_WM_KILLFOCUS()
	ON_COMMAND(ID_EDIT_GOTO, OnEditGoto)
	ON_UPDATE_COMMAND_UI(ID_EDIT_GOTO, OnUpdateEditGoto)
	ON_WM_MDIACTIVATE()
	ON_COMMAND(ID_VIEW_REFRESH, OnViewRefresh)
	ON_UPDATE_COMMAND_UI(ID_VIEW_REFRESH, OnUpdateViewRefresh)
	ON_COMMAND(ID_EDIT_SEARCH, OnEditSearch)
	ON_UPDATE_COMMAND_UI(ID_EDIT_SEARCH, OnUpdateEditSearch)
	ON_COMMAND(ID_EDIT_SEARCHNEXT, OnEditSearchnext)
	ON_UPDATE_COMMAND_UI(ID_EDIT_SEARCHNEXT, OnUpdateEditSearchnext)
	ON_COMMAND(ID_SHIFTRETURN, OnShiftreturn)
	ON_COMMAND(ID_GROUP_MEMORY, OnGroupMemory)
	ON_COMMAND(ID_MAP, OnMap)
	ON_UPDATE_COMMAND_UI(ID_MAP, OnUpdateMap)    
	ON_UPDATE_COMMAND_UI(ID_GROUP_MEMORY, OnUpdateGroupMemory)
	ON_WM_SYSCOMMAND()
	ON_WM_NCHITTEST()
	ON_COMMAND(ID_VIEW_SHORTLINE, OnViewShortline)
	ON_UPDATE_COMMAND_UI(ID_VIEW_SHORTLINE, OnUpdateViewShortline)
	ON_WM_LBUTTONDBLCLK()
	ON_COMMAND(ID_STK_TAB, OnStkTab)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

UINT CMemoryWindow::OnNcHitTest(CPoint point)
{
   // TODO: Add your message handler code here and/or call default
   unsigned char uchCpuStatus;
   UINT nHitTest = 0;
   nHitTest = CMDIChildWnd::OnNcHitTest(point);          
   
   if (GetCpuStatus(uchCpuStatus)) {
      if ( 1 != uchCpuStatus ) {       // Is not on GO status (STATUS_GO)
         return nHitTest; /*CMDIChildWnd::OnNcHitTest(point);*/
      }
      else {            // On GO
         //if ( SrcEmu.m_isRunAccess ) {       // GO and Run Access
         //   return CMDIChildWnd::OnNcHitTest(point);
         //}
         //else {         // Go and Run access off
         switch ( nHitTest ) {
               /*
            case HTBORDER     :
            case HTBOTTOM       :
            case HTBOTTOMLEFT   : 
            case HTBOTTOMRIGHT  :  
            case HTHSCROLL      :
            case HTLEFT         :
            case HTRIGHT        :
            case HTTOP          :
            case HTTOPLEFT      :
            case HTTOPRIGHT     :
            case HTVSCROLL      :
                ShowStatusGo();
                return HTERROR;
            */                      
            case HTZOOM         :
            case HTSYSMENU      :            
            case HTCAPTION      :
            //case HTCLIENT       :
            case HTMINBUTTON    :            
                return nHitTest;
                
            default:
                ShowStatusGo();
                 return HTERROR;   
                   
         }
         //}   
      }         
   }
   else
      return HTERROR;
}

BOOL
ReadMemWndIni()
{
    CString defaultini = "1 0 1 0 1 0";        
    int mem1area, mem2area, mem3area;
    long mem1addr, mem2addr, mem3addr;

    CString strBuffer = AfxGetApp()->
        GetProfileString("MemWindow", "MemWindow", defaultini); 
           
    int nRval = sscanf(strBuffer, "%d %lu %d %lu %d %lu", 
                       &mem1area, &mem1addr, 
                       &mem2area, &mem2addr,
                       &mem3area, &mem3addr);
    if(nRval != 6)  return FALSE;
    
    sdw_Mem1StartAddr = mem1addr&0xfffffff0;
    sdw_Mem2StartAddr = mem2addr&0xfffffff0;
    sdw_Mem3StartAddr = mem3addr&0xfffffff0;
    
    if(g_nBankNum==0)
    {
    	if(mem1area>5)
    		mem1area=1;
    	if(mem2area>5)
    		mem2area=1;
    	if(mem3area>5)
    		mem3area=1;
    }
    else if(g_nBankNum==2)
    {
    	if(mem1area>7||mem1area==1)
    		mem1area=6;
    	if(mem2area>7||mem2area==1)
    		mem2area=6;
    	if(mem3area>7||mem3area==1)
    		mem3area=6;
    }
    else if(g_nBankNum==4)
    {
    	if(mem1area==1)
    		mem1area=6;
    	if(mem2area==1)
    		mem2area=6;
    	if(mem3area==1)
    		mem3area=6;
    }

    sb_Mem1Space = (unsigned char)mem1area;
    sb_Mem2Space = (unsigned char)mem2area;
    sb_Mem3Space = (unsigned char)mem3area;
    
    return TRUE;
}

BOOL
WriteMemWndIni()
{
    char szBuffer[100];
    int mem1area, mem2area, mem3area;
    long mem1addr, mem2addr, mem3addr;
    
    mem1addr = (long)sdw_Mem1StartAddr;
    mem2addr = (long)sdw_Mem2StartAddr;
    mem3addr = (long)sdw_Mem3StartAddr;

    mem1area = (int)sb_Mem1Space;
    mem2area = (int)sb_Mem2Space;
    mem3area = (int)sb_Mem3Space;

    int nRval = sprintf(szBuffer, "%d %lu %d %lu %d %lu", 
                        mem1area, mem1addr, 
                        mem2area, mem2addr,
                        mem3area, mem3addr);
    if(nRval == -1) return FALSE;                 
    
    AfxGetApp()->WriteProfileString("MemWindow", "MemWindow", szBuffer);
    
    return TRUE;
}


/////////////////////(EOF of NWMEM.CPP)/////////////////////////////
