/***************************************************************************
**
**    $Header$
**                  
**    $Log$
** 
****************************************************************************/

/////////////////////////////////////////////////////////////////////////////
//
//  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 "flttool.h"
#include "uicom2.h"
#include "colors.h"
#include "cpudlg.h"
#include "cpuwin.h"           
//#include "hosterrs.h"  
//#include "errcodec.h"

//next two line is just for test regmap.dll
#include "address.h"
#include "regsvr.h"

//#include  "contain.h"

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

/////////////////////////////////////////////////////////////////////////////
//
//  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(gb_isCpuOn)    return;
    
    ////////////////////////////////////////
    gp_CpuWnd = 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 *)gp_CpuWnd)->Create("CPU", WS_CHILD
        |WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL|dwFlag,
        CFrameWnd::rectDefault, pParent))
        ASSERT(0);                               
        
    // set the flag        
    gb_isCpuOn = TRUE;              
    
    /*if(x_dwStyle)                
    	gp_CpuWnd->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
    return  GetRegs();
}

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

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
CCpuWindow::~CCpuWindow()
{  
    gb_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;
}

/////////////////////////////////////////////////////////////////////////////
//
//  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;
    if(RegSelect[nIdx]==0){
        DWORD uVal;
        char strBank[5], pcName[7];
        
        memset(pcName,' ',7);
        memset(strBank,' ',5);
        strcpy(pcName, "PC");           
        uVal = m_NewValue[RegSelect[nIdx]];
        wsprintf(strBank, "(P%d)", int(uVal>>16));
        strcat(pcName, strBank);
        nLen = 6;
        pdc->TextOut(x + 1 + x1, y + 1, pcName, nLen);
    }      
    else 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, DWORD& uVal, BOOL isNormal)
{
    ASSERT_VALID(pdc);

    int x, y;
    char tmp1[VAL_LEN+1], tmp2[VAL_LEN+1];     
    
    //added by dragon
    CRegItem regItem;
    
    regItem.wSerial = (WORD)RegSelect[nIdx];
    regItem.wWindow = WINDOW_NONE;
    
    if(!ByteFromRegID(&regItem)) {
        AfxMessageBox("Error: Identifier of register is not correct");
        return ;
    }
    
    if(nCpuRadix == CPU_HEX) {
        if(regItem.wLen == 1){  
            uVal = U8(uVal);
            x = wsprintf(tmp2, "%02X", (U8)uVal);
        }                                          
        else{
            uVal = U16(uVal);
            x = wsprintf(tmp2, "%04X", (UINT)uVal);
        }
    } 
    else{
        if(regItem.wLen == 1){
            uVal = U8(uVal);
            x = wsprintf(tmp2, "%u", (U8)uVal);
        }
        else{
            uVal = U16(uVal);
            x = wsprintf(tmp2, "%u", (UINT)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 + 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();
    GetRegs();

    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();
    GetRegs();
    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();
    GetRegs();
    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();
    GetRegs();
    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()
{
//ADDRESS	addr;
//BOOL	ret;
//char	buf[100];
//char	str[20];
    
	// TODO: Add your message handler code here and/or call default
	//just for test regmap.dll
    // 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);
}
