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

/////////////////////////////////////////////////////////////////////////////
//
//  File name:  CPUWIN.CPP
//
//  Description:The implement file for the class: CCpuWindow
//
//  Author:     Roger Zhang
//
//  Date:       04/12/95
//
//  Modification:
//
//      1. 04/12/95, Initial version 
//
//
//  Copyright (C) 1995 Microtek International. All rights reserved.
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "resource.h"

#include "uicom.h"
#include "colors.h"
#include "cpucom.h"
#include "cpucfg.h"
#include "cpureg.h"
#include "cpuwin.h"
#include "hosterrs.h"  
#include "errcodec.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
           
/////////////////////////////////////////////////////////////////////////////
//  Global functions
/////////////////////////////////////////////////////////////////////////////
WINDOWPLACEMENT x_wp;
static DWORD x_dwStyle = 0;
static CRect x_rc = CFrameWnd::rectDefault;

/////////////////////////////////////////////////////////////////////////////
long SrcGetPC(void)
{
    if(!CpuGetAllReg()) {
        ErrDisplayError(ER_PRE_COMMUNICATION);
        return 0x10000L;
    }
    
    return long(RegValue[0]);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   CpuOpenWindow
//
//  Description: Open the CPU window
//
//  Input:  
//      pParent --  the parent window 
//      isHide  --  Hide the window when open 
//
//  Output: NULL
//
//  Return: NULL
//
/////////////////////////////////////////////////////////////////////////////
void CpuOpenWindow(CMDIFrameWnd * pParent, BOOL isHide)
{               
    // if window already opened, do nothing
    if(isCpuOn)    return;                 
    
    ////////////////////////////////////////
    pCpuWnd = new CCpuWindow;               
    
    // set flags depending on whether hide the window          
    DWORD dwFlag = isHide ? 0 : WS_VISIBLE;          
    //DWORD dwFlag = (!x_dwStyle && !isHide) ? WS_VISIBLE : 0;
    
    // if can't create, then the application halt
    if(!((CCpuWindow *)pCpuWnd)->Create("CPU", WS_CHILD
        |WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL|dwFlag,
        CFrameWnd::rectDefault, pParent))
        ASSERT(0);                               
        
    // set the flag        
    isCpuOn = TRUE;              
    
    /*if(x_dwStyle)                
    	pCpuWnd->SetWindowPlacement(&x_wp);*/
}

/////////////////////////////////////////////////////////////////////////////
//  Static member variable initialization
/////////////////////////////////////////////////////////////////////////////
CMenu NEAR CCpuWindow::m_menu;                              


/////////////////////////////////////////////////////////////////////////////
// CCpuWindow

IMPLEMENT_DYNCREATE(CCpuWindow, CMDIChildWnd)

/////////////////////////////////////////////////////////////////////////////
// Constructor/Destructor
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL CCpuWindow::Create(LPCSTR szTitle, LONG style,
    const RECT& rect, CMDIFrameWnd * pParent)
{
    // Setup the shared m_menu
    if(m_menu.m_hMenu == NULL)
        m_menu.LoadMenu(IDR_CPU);
    m_hMenuShared = m_menu.m_hMenu;
    
    /*CRect rc;
    if(x_dwStyle)	style |= x_dwStyle;      
    else if(x_rc != CFrameWnd::rectDefault) {
    	rc = x_rc;
    } else rc = rect;	
    x_dwStyle = 0;*/

    const char * pszCpuClass =
        AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,
            LoadCursor(NULL, IDC_ARROW),
            (HBRUSH)(GetStockObject(LTGRAY_BRUSH)),
            AfxGetApp()->LoadIcon(IDI_CPU));
    if(!(CMDIChildWnd::Create(pszCpuClass, szTitle,
        style, rect, pParent))) 
        return FALSE;

    // Get register value
    #ifdef _ZLR_
    return  GetRegs();
    #else
    return TRUE;
    #endif
    
	SaveOldValue();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
CCpuWindow::CCpuWindow()
: m_nFont(STANDARD_FONT), m_ptFirst(0,0), m_isSel(FALSE)
{
    m_nIDHelp = IDR_CPU;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
CCpuWindow::~CCpuWindow()
{  
    isCpuOn = FALSE;
}                        

void CCpuWindow::SaveOldValue(void)
{
    for(int i = 0; i < MAX_REGISTERS; i ++) {
     	m_OldValue[i] = m_NewValue[i];
    }
}

BOOL CCpuWindow::GetRegs(void)
{
 	if(!CpuGetAllReg())	return	FALSE;
 	 	
	for(int i = 0; i < MAX_REGISTERS; i ++)
		m_NewValue[i] = RegValue[i];
		
	return TRUE;
}

/*BOOL CCpuWindow::PreCreateWindow(CREATESTRUCT & cs)
{                                                  
    return CMDIFrameWnd::PreCreateWindow(cs);
} */

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Get char coordinates for register nIdx
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::CalcXY(int nIdx, int &x, int &y)
{
    ASSERT(nIdx >= 0 && nIdx < ::nCurRegs);
    
    if(nIdx < 0)    nIdx = 0;
    else if(nIdx > ::nCurRegs - 1)    nIdx = ::nCurRegs - 1;
    x = nIdx % m_nCols;
    y = nIdx / m_nCols;
}              

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Get point coordinates
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::CalcPoint(BOOL isName, int nIdx, int &x, int &y)
{   
    CalcXY(nIdx, x, y);
    y = m_szGap.cy + y * (m_szName.cy + m_szGap.cy);
    x = m_szGap.cx + x * (m_szName.cx + m_szGap.cx 
        + m_szValue.cx + 2 * m_szGap.cx);
    if(!isName)  x += m_szName.cx + m_szGap.cx; 
    x -= m_ptFirst.x; y -= m_ptFirst.y;    
}                                                  

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Draw register cell frame
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::DrawFrame(CDC * pdc, BOOL isName, int nIdx, int nConvex)
{
    ASSERT_VALID(pdc);

    CPoint pt;
    CalcPoint(isName, nIdx, pt.x, pt.y);
    if(isName)  ::DrawFrame(pdc, CRect(pt.x, pt.y, 
        pt.x + m_szName.cx - 1, pt.y + m_szName.cy - 1), nConvex);
    else    ::DrawFrame(pdc, CRect(pt.x, pt.y, 
        pt.x + m_szValue.cx - 1, pt.y + m_szValue.cy - 1), nConvex);
}                                                 

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Show register name
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::ShowRegName(CDC * pdc, int nIdx)
{
    ASSERT_VALID(pdc);

    int x, y;
    CalcPoint(TRUE, nIdx, x, y);    
    pdc->SelectStockObject(m_nFont);
    pdc->SetBkColor(PALETTEINDEX(COLOR_LTGRAY));
    pdc->SetTextColor(PALETTEINDEX(COLOR_BLACK));
    int nLen = strlen(RegName[RegSelect[nIdx]]);
    int x1 = (m_szName.cx - 2 - nLen * m_szFont.cx) / 2;
    pdc->TextOut(x + 1 + x1, y + 1, RegName[RegSelect[nIdx]], nLen);
}
                                                             
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Show register value
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::ShowRegValue(CDC * pdc, int nIdx, UINT uVal, BOOL isNormal)
{
    ASSERT_VALID(pdc);

    int x, y;
    char tmp1[VAL_LEN+1], tmp2[VAL_LEN+1];         
    
    if(nCpuRadix == CPU_HEX) {
        if(RegSelect[nIdx] > 1)
            x = wsprintf(tmp2, "%02.2X", uVal);
        else
            x = wsprintf(tmp2, "%04.4X", uVal);
    } else {               
        x = wsprintf(tmp2, "%u", uVal);
    }
    memset(tmp1, ' ', VAL_LEN);
    strcpy(tmp1 + VAL_LEN - x, tmp2);
    
    CalcPoint(FALSE, nIdx, x, y);    
    pdc->SelectStockObject(m_nFont);
    if(isNormal) {
        pdc->SetBkColor(PALETTEINDEX(COLOR_LTGRAY));
        pdc->SetTextColor(PALETTEINDEX(COLOR_BLACK));
    } else {
        pdc->SetTextColor(PALETTEINDEX(COLOR_WHITE));
        pdc->SetBkColor(PALETTEINDEX(COLOR_BLUE));
    }
    //pdc->TextOut(x + 1, y + 1, tmp1, VAL_LEN);
    pdc->TextOut(x + 3, y + 1, tmp1, VAL_LEN);
}                                                    
                 
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Called when change size or config registers
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::Resize(int cx, int cy)
{
    SaveOldValue();
    #ifdef _ZLR_
    GetRegs();
    #endif

    CSize sz(m_szName.cx + m_szGap.cx + m_szValue.cx + m_szGap.cx * 2,
        m_szGap.cy + m_szName.cy);
    m_nCols = cx / sz.cx;
    if(m_nCols < 1)   m_nCols = 1;
    m_ptFirst.x = m_ptFirst.y = 0;
    m_nRows = (nCurRegs + m_nCols - 1) / m_nCols;
    
    if(sz.cx > cx) 
        m_szScroll.cx = sz.cx - cx;
    else m_szScroll.cx = 0;
    SetScrollRange(SB_HORZ, 0, m_szScroll.cx);
    
    if(m_nRows * sz.cy > cy)    
        m_szScroll.cy = m_nRows * sz.cy - cy;
    else m_szScroll.cy = 0;
    SetScrollRange(SB_VERT, 0, m_szScroll.cy);
    
    SetScrollPos(SB_HORZ, m_ptFirst.x);
    SetScrollPos(SB_VERT, m_ptFirst.y);
}

BEGIN_MESSAGE_MAP(CCpuWindow, CMDIChildWnd)
    //{{AFX_MSG_MAP(CCpuWindow)
    ON_MESSAGE(XM_REPAINT, OnXMRepaint)
    ON_WM_PAINT()
    ON_WM_CREATE()
    ON_WM_SIZE()
    ON_WM_HSCROLL()
    ON_WM_VSCROLL()
    ON_WM_LBUTTONDOWN()
    ON_COMMAND(ID_VIEW_CONFIGREGISTERS, OnViewConfigregisters)
    ON_COMMAND(ID_VIEW_DECIMAL, OnViewDecimal)
    ON_UPDATE_COMMAND_UI(ID_VIEW_DECIMAL, OnUpdateViewDecimal)
    ON_COMMAND(ID_VIEW_HEXADECIMAL, OnViewHexadecimal)
    ON_UPDATE_COMMAND_UI(ID_VIEW_HEXADECIMAL, OnUpdateViewHexadecimal)
    ON_WM_GETMINMAXINFO()
    ON_WM_MDIACTIVATE()
    ON_WM_RBUTTONDOWN()
    ON_WM_SETCURSOR()
    ON_COMMAND(ID_RUN_RESET, OnRunReset)
    ON_COMMAND(ID_VIEW_REFRESH, OnViewRefresh)
	ON_WM_CLOSE()
	ON_WM_CHAR()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//                  CCpuWindow message handlers                            //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
// User defined message handler
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
LONG CCpuWindow::OnXMRepaint(UINT /*wParam*/, LONG /*lParam*/)
{
	if(!m_isSel)	SaveOldValue();
	m_isSel = FALSE;
    GetRegs();
    InvalidateRect(NULL);
    return  0;
}

/////////////////////////////////////////////////////////////////////////////
// Window standard message handler
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::OnPaint()
{
    CPaintDC dc(this); // device context for painting
    
    // TODO: Add your message handler code here   
    for(int i = 0; i < ::nCurRegs; i ++) {
        DrawFrame(&dc, TRUE, i, 1);
        ShowRegName(&dc, i);
        DrawFrame(&dc, FALSE, i, 0);
        if(m_NewValue[RegSelect[i]] != m_OldValue[RegSelect[i]])
            ShowRegValue(&dc, i, m_NewValue[RegSelect[i]], 0);
        else
            ShowRegValue(&dc, i, m_NewValue[RegSelect[i]], 1);
    }    

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

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
int CCpuWindow::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
    
    // TODO: Add your specialized creation code here

    if(nCpuRadix == CPU_HEX)    SetWindowText("CPU[Hex]");
    else    SetWindowText("CPU[Dec]");
          
    // Get font size          
    TEXTMETRIC tm;
    CDC * pDC = GetDC();
    pDC->SelectStockObject(m_nFont);
    pDC->GetTextMetrics(&tm);
    ReleaseDC(pDC); 

    m_szFont.cy = tm.tmHeight + tm.tmExternalLeading;
    m_szFont.cx = tm.tmAveCharWidth;
    
    //m_szValue.cx = m_szFont.cx * VAL_LEN + 2;
    m_szValue.cx = m_szFont.cx * VAL_LEN + 6;
    m_szValue.cy = m_szFont.cy + 2;
    m_szName.cx = m_szFont.cx * NAME_LEN + 2;
    m_szName.cy = m_szValue.cy;
    m_szGap.cx = m_szFont.cx;
    m_szGap.cy = 4;
    
    return 0;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::OnSize(UINT nType, int cx, int cy)
{
    CMDIChildWnd::OnSize(nType, cx, cy);
    
    // TODO: Add your message handler code here
    Resize(cx, cy);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
    // TODO: Add your message handler code here and/or call default
    CRect rect;
    GetClientRect(&rect);     
    int i;    
         
    switch(nSBCode) {
        case SB_LINELEFT:                 
            if(m_ptFirst.x <= 0)  break;
            if(m_ptFirst.x > 7)   i = 8;
            else i = m_ptFirst.x; 
            m_ptFirst.x -= i;;
            ScrollWindow(i, 0);
            SetScrollPos(SB_HORZ, m_ptFirst.x);
            break;
        case SB_LINERIGHT:
            if(m_ptFirst.x >= m_szScroll.cx)    break;
            if(m_ptFirst.x < m_szScroll.cx - 7) i = 8;
            else i = m_szScroll.cx - m_ptFirst.x;
            m_ptFirst.x += i;;
            ScrollWindow(-i, 0);
            SetScrollPos(SB_HORZ, m_ptFirst.x);
            break;     
        case SB_PAGELEFT: 
            if(m_ptFirst.x == 0)    break;
            if(m_ptFirst.x > rect.Width()) {
                ScrollWindow(rect.Width(), 0);
                m_ptFirst.x -= rect.Width();
            }
            else {
                ScrollWindow(m_ptFirst.x, 0);
                m_ptFirst.x = 0;
            }
            SetScrollPos(SB_HORZ, m_ptFirst.x);
            break;
        case SB_PAGERIGHT:
            if(m_ptFirst.x >= m_szScroll.cx)    break;
            if(m_ptFirst.x + rect.Width() <= m_szScroll.cx) {
                ScrollWindow(-rect.Width(), 0);
                m_ptFirst.x += rect.Width();
            }
            else {
                ScrollWindow(-(m_szScroll.cx - m_ptFirst.x), 0);
                m_ptFirst.x = m_szScroll.cx;
            }
            SetScrollPos(SB_HORZ, m_ptFirst.x);
            break;
        case SB_THUMBPOSITION:           
        case SB_THUMBTRACK:
            if(int(nPos) == m_ptFirst.x) break;
            ScrollWindow(m_ptFirst.x - nPos, 0);
            m_ptFirst.x = nPos;
            SetScrollPos(SB_HORZ, m_ptFirst.x);
            break;
    }          

    CMDIChildWnd::OnHScroll(nSBCode, nPos, pScrollBar);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
    // TODO: Add your message handler code here and/or call default
    CRect rect;
    GetClientRect(&rect);                   
    int i;

    switch(nSBCode) {
        case SB_LINEUP:
            if(m_ptFirst.y <= 0)  break;
            if(m_ptFirst.y > 7)   i = 8;
            else i = m_ptFirst.y;
            m_ptFirst.y -= i;
            ScrollWindow(0, i);
            SetScrollPos(SB_VERT, m_ptFirst.y);
            break;
        case SB_LINEDOWN:    
            if(m_ptFirst.y >= m_szScroll.cy)    break;
            if(m_ptFirst.y < m_szScroll.cy - 7) i = 8;
            else i = m_szScroll.cy - m_ptFirst.y;
            m_ptFirst.y += i;;
            ScrollWindow(0,-i);
            SetScrollPos(SB_VERT, m_ptFirst.y);
            break;
        case SB_PAGEUP: 
            if(m_ptFirst.y == 0)    break;
            if(m_ptFirst.y > rect.Height()) {
                ScrollWindow(0, rect.Height());
                m_ptFirst.y -= rect.Height();
            }
            else {
                ScrollWindow(0, m_ptFirst.y);
                m_ptFirst.y = 0;
            }
            SetScrollPos(SB_VERT, m_ptFirst.y);
            break;
        case SB_PAGEDOWN:
            if(m_ptFirst.y >= m_szScroll.cy)    break;
            if(m_ptFirst.y + rect.Height() <= m_szScroll.cy) {
                ScrollWindow(0, -rect.Height());
                m_ptFirst.y += rect.Height();
            }
            else {
                ScrollWindow(0, -(m_szScroll.cy - m_ptFirst.y));
                m_ptFirst.y = m_szScroll.cy;
            }
            SetScrollPos(SB_VERT, m_ptFirst.y);
            break;
        case SB_THUMBPOSITION:           
        case SB_THUMBTRACK:
            if(int(nPos) == m_ptFirst.y) break;
            ScrollWindow(0, m_ptFirst.y - nPos);
            m_ptFirst.y = nPos;
            SetScrollPos(SB_VERT, m_ptFirst.y);
            break;
    }          
    
    CMDIChildWnd::OnVScroll(nSBCode, nPos, pScrollBar);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: Add your message handler code here and/or call default
    CClientDC dc(this);
    
    
    int x, y;            
    CRect rect;  
    CRegisterDialog * pDlg;
    for(int i = 0; i < nCurRegs; i ++) {
        CalcPoint(TRUE, i, x, y);      
        rect.SetRect(x, y, x + m_szName.cx, y + m_szName.cy);
        if(rect.PtInRect(point)) {
            DrawFrame(&dc, TRUE, i, 0);
            pDlg = new CRegisterDialog(RegSelect[i], this);
            x = pDlg->DoModal();
            delete pDlg;
            DrawFrame(&dc, TRUE, i, 1);
            break;
        }
    }                                           
    
	if(x == IDOK) {
		SaveOldValue();    
	    m_isSel = TRUE;
	    GetRegs();
	    if(m_OldValue[0] == m_NewValue[0])
	    	RepaintWindows();
	    else
	    	OnEmulation();
    }	
    

    // Added by Chen
    SetFocus();

    CMDIChildWnd::OnLButtonDown(nFlags, point);
}                                                              

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
    // TODO: Add your message handler code here and/or call default
    CMDIChildWnd::OnGetMinMaxInfo(lpMMI);
    lpMMI->ptMinTrackSize.x = 150;    
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::OnMDIActivate(BOOL bActivate, CWnd* pActivateWnd, 
    CWnd* pDeactivateWnd)
{
    CMDIChildWnd::OnMDIActivate(bActivate, pActivateWnd, pDeactivateWnd);
    
    // TODO: Add your message handler code here
    //SaveOldValue();
    #ifdef _ZLR_
    GetRegs();
    #endif         
    
    InvalidateRect(NULL);
    
    if(bActivate && pActivateWnd == this)
        GetMDIFrame()->SendMessage(XM_MDIACTIVE, WORD(bActivate), 
            LONG(WID_CPU));
    else if(!bActivate && !pActivateWnd)
        GetMDIFrame()->SendMessage(XM_MDIACTIVE, WORD(bActivate)); 
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Execute Local Menu
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::OnRButtonDown(UINT /*nFlags*/, CPoint point)
{
    // TODO: Add your message handler code here and/or call default
    
    CMenu * pLocalMenu = new CMenu;
    ASSERT( NULL != pLocalMenu );

    pLocalMenu->CreatePopupMenu();
    pLocalMenu->AppendMenu(MF_STRING, ID_RUN_RESET, "&Reset");
//    pLocalMenu->AppendMenu(MF_SEPARATOR);
//    pLocalMenu->AppendMenu(MF_STRING, ID_GROUP_CONFIGURE,
//                            "Configure &Processor...");
    pLocalMenu->AppendMenu(MF_SEPARATOR);
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_HEXADECIMAL,
                            "&Hexadecimal");
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_DECIMAL, "&Decimal");
    pLocalMenu->AppendMenu(MF_SEPARATOR);
    pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_CONFIGREGISTERS,
                            "C&onfigure Registers...");
    pLocalMenu->SetMenuItemBitmaps(ID_VIEW_HEXADECIMAL, MF_BYCOMMAND, 
        &bmpMenuUncheck, &bmpMenuCheck);
    pLocalMenu->SetMenuItemBitmaps(ID_VIEW_DECIMAL, MF_BYCOMMAND, 
        &bmpMenuUncheck, &bmpMenuCheck);

    ClientToScreen(&point);
    pLocalMenu->TrackPopupMenu(TPM_LEFTALIGN, point.x, point.y, this);
    delete pLocalMenu;

//    CMDIChildWnd::OnRButtonDown(nFlags, point);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL CCpuWindow::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);
}

/////////////////////////////////////////////////////////////////////////////
// Menu command handler -- View Submenu
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::OnViewConfigregisters()
{
    // TODO: Add your command handler code here
    CRegcfgDialog dlgRegcfg(this);
    int i, j;
    CRect rect;
    if(dlgRegcfg.DoModal() == IDOK) {
        for(i = 0, j = 0; i < nMaxReg; i ++) {
            if(dlgRegcfg.m_Reg[i] == TRUE)  RegSelect[j++] = i;
        }
        nCurRegs = j;
        GetClientRect(rect);
        Resize(rect.Width(), rect.Height());
        InvalidateRect(NULL);       
    }
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::OnViewDecimal()
{
    // TODO: Add your command handler code here
    SaveOldValue();
    #ifdef _ZLR_
    GetRegs();
    #endif
    InvalidateRect(NULL);
    if(nCpuRadix != CPU_DEC) {
        nCpuRadix = CPU_DEC;    
        SetWindowText("CPU[Dec]");
        InvalidateRect(NULL);
    }
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::OnUpdateViewDecimal(CCmdUI* pCmdUI)
{
    // TODO: Add your command update UI handler code here
    pCmdUI->SetRadio(nCpuRadix == CPU_DEC);    
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::OnViewHexadecimal()
{
    // TODO: Add your command handler code here
    SaveOldValue();
    #ifdef _ZLR_
    GetRegs();
    #endif
    InvalidateRect(NULL);
    if(nCpuRadix != CPU_HEX) {
        nCpuRadix = CPU_HEX;    
        SetWindowText("CPU[Hex]");
        InvalidateRect(NULL);
    }
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::OnUpdateViewHexadecimal(CCmdUI* pCmdUI)
{
    // TODO: Add your command update UI handler code here
    pCmdUI->SetRadio(nCpuRadix == CPU_HEX);    
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::OnViewRefresh()
{
    // TODO: Add your command handler code here
    SaveOldValue();
    GetRegs();
    InvalidateRect(NULL); 
}

/////////////////////////////////////////////////////////////////////////////
// Menu command handler -- Run Submenu
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CCpuWindow::OnRunReset()
{
    // TODO: Add your command handler code here
    if(AfxMessageBox("Confirm reset operation?", MB_YESNO|MB_ICONQUESTION)
        == IDNO)    
        return;
        
    DoReset();    
    OnEmulation();
}

void CCpuWindow::OnClose()
{
	// TODO: Add your message handler code here and/or call default
/*	if(IsIconic())	    x_dwStyle = WS_MINIMIZE;
	else if(IsZoomed()) x_dwStyle = WS_MAXIMIZE;
	GetWindowRect(x_rc);
	GetParent()->ScreenToClient(x_rc);*/
/*	x_dwStyle = 1;
	GetWindowPlacement(&x_wp);
	x_wp.flags = 0;
	if(IsZoomed()) {
	    x_wp.flags |= WPF_RESTORETOMAXIMIZED;
	}*/
	
	CMDIChildWnd::OnClose();
}
//////////////////////////////////(EOF)//////////////////////////////////////

void CCpuWindow::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: Add your message handler code here and/or call default
	
	CMDIChildWnd::OnChar(nChar, nRepCnt, nFlags);
}
