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

/////////////////////////////////////////////////////////////////////////////
//
//  File name:  UICOM.CPP
//
//  Description:The implement file of common declare for GUI
//
//  Author:     Roger Zhang
//
//  Date:       03/08/95
//
//  Modification:
//
//      1. 03/08/95, Initial version 
//
//
//  Copyright (C) 1995 Microtek International. All rights reserved.
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "resource.h"
                     
#include "colors.h"                     
#include "uicom.h"
#include "bmemwnd.h"
#include "cpust.h"

// Added by Chen, 06/21/96.
#include "spamsg.h"
#include "spafrm.h"
#include "spaline.h"
#include "spatdoc.h"
#include "spatvw.h"
#include "direct.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
                             
extern char szAppPath[_MAX_PATH+1];                             
/////////////////////////////////////////////////////////////////////////////                  
// Added by Chen, 06/21/96.
extern CSpaCodeFrame* pSpaCodeWnd;
void CloseCodeCoverageWindow(void);

/////////////////////////////////////////////////////////////////////////////
int		g_nBankNum=0;			//0: not support bank; No B1 B2 B3 B4 space
								//2: support 2 banks;  No B3 B4 space
								//4: supprot 4 banks. 
int		g_nCurrentBank=1;		//1-4
int		g_nPort=1; 
int     g_nPortLowBit=0;
int     g_nPortHighBit=1;
int     g_nSignal;
/////////////////////////////////////////////////////////////////////////////                  
BOOL    isInsertOn = FALSE;     

/////////////////////////////////////////////////////////////////////////////
BOOL    isShellOn     = FALSE;
BOOL    isSourceOn    = FALSE;
BOOL    isBrowseOn    = FALSE;
BOOL    isVariableOn  = FALSE;
BOOL    isStackOn     = FALSE;
BOOL    isCpuOn       = FALSE;
BOOL    isTraceOn     = FALSE;
BOOL    isMemOn[MAX_MEM_WND] = { FALSE, FALSE, FALSE };
BOOL    isBMemOn      = FALSE; // lane
BOOL    isNewMemoryOn = FALSE; // lane
BOOL    isPeriOn      = FALSE;

/////////////////////////////////////////////////////////////////////////////
CMDIChildWnd    * pShellWnd;
CMDIChildWnd    * pSourceWnd; 
CMDIChildWnd    * pBrowseWnd; 
CMDIChildWnd    * pVariableWnd;
CMDIChildWnd    * pStackWnd;
CMDIChildWnd    * pCpuWnd;
CMDIChildWnd    * pTraceWnd;                         
CMDIChildWnd    * pMemWnd[MAX_MEM_WND];
CMDIChildWnd    * pBMemWnd; // lane
CMultiDocTemplate* pMemDocTemplate;
CMultiDocTemplate* pBMemDocTemplate;
CMultiDocTemplate* pPeriDocTemplate;
CMDIChildWnd    * pNewMemoryWnd;
CMDIChildWnd    * pPeriWnd;

///////////////////////////////////////////////////////////////////////////// 
//By Lane;
int nTraceViewOption;  //"1" for Bus; "2" for Instruction;
BOOL	g_bTraceClear=FALSE;

/////////////////////////////////////////////////////////////////////////////
CString strIncludeFile;

BOOL isSaveLayoutOnExit = TRUE;

/////////////////////////////////////////////////////////////////////////////
CBitmap bmpMenuCheck;
CBitmap bmpMenuUncheck;

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   TestKey
//
//  Description: Test if a specified key pressed
//
//  Input:  
//      wKey -- Key code
//
//  Output: None
//
//  Return: 1 -- The key has been pressed
//          0 -- The key not been pressed
//
/////////////////////////////////////////////////////////////////////////////
int TestKey(WORD wKey)
{   
    MSG msg;
    if(PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST,
        PM_NOREMOVE|PM_NOYIELD)) {
        PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST,
            PM_REMOVE|PM_NOYIELD);
        if(msg.message == WM_KEYDOWN && msg.wParam == wKey) 
            return  1;        
    }            
    return  0;
}
                               
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   TestAnyKey
//
//  Description: Test if there is any key pressed
//
//  Input:  None
//
//  Output: None
//
//  Return: 1 -- Find key pressed
//          0 -- No key pressed
//
/////////////////////////////////////////////////////////////////////////////
int TestAnyKey(void)
{   
    MSG msg;
    if(PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST,
        PM_NOREMOVE|PM_NOYIELD)) {
        PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST,
            PM_REMOVE|PM_NOYIELD);
        if(msg.message == WM_KEYDOWN) 
            return  1;                                    
    }            
    return  0;
}
                               
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   DrawFrame
//
//  Description: Draw a rectangle frame
//
//  Input:  
//      pDC -- Pointer to CDC
//      rect -- the size and position of the frame
//      nConvex -- the shape of the frame
//                  1 -- Convex frame, 0 -- Concave frame
//
//  Output: None
//
//  Return: None
//
/////////////////////////////////////////////////////////////////////////////
void DrawFrame(CDC * pDC, CRect &rect, int nConvex)
{        
    CPen pen1(PS_SOLID, 1, PALETTEINDEX(COLOR_DKGRAY));    
    CPen pen2(PS_SOLID, 1, PALETTEINDEX(COLOR_WHITE));    
    CPen * penOld;
    
    pDC->MoveTo(rect.left, rect.bottom);

    if(nConvex) penOld = pDC->SelectObject(&pen2);
    else    penOld = pDC->SelectObject(&pen1);

    pDC->LineTo(rect.left, rect.top);
    pDC->LineTo(rect.right, rect.top);

    if(nConvex) pDC->SelectObject(&pen1);
    else    pDC->SelectObject(&pen2);

    pDC->LineTo(rect.right, rect.bottom);
    pDC->LineTo(rect.left, rect.bottom);

    pDC->SelectObject(penOld);
}             

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   isspace
//
//  Description: Test if the specified char is a white space
//
//  Input:  
//      ch -- the char to test
//
//  Output: None
//
//  Return: TRUE -- the char is a white space
//
/////////////////////////////////////////////////////////////////////////////
static BOOL isspace(char ch)
{
    return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r';
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   SkipHeadWS
//
//  Description: Skip head white space of the string
//
//  Input:  
//      psz -- the string
//
//  Output: None
//
//  Return: the string that been processed
//
/////////////////////////////////////////////////////////////////////////////
static char * SkipHeadWS(char * psz)
{
    while(isspace(*psz))    ++ psz;
    return psz;
}              

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
static void CutTailWS(char * psz)
{
    int l = strlen(psz);
    if(!l)  return;     
    psz += l - 1;
    while(isspace(*psz))    -- psz;
    *(psz+1) = '\0';
}                

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Transfer a string to a decimal number
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
static BOOL Dec2Num(char * psz, DWORD & dwVal)
{
    char * p = psz;
                   
    int l = strlen(p);
    if(l == 0)  return FALSE;
                              
    DWORD dw = 1;                              
    dwVal = 0;      
    p += l - 1;
    for(int i = 0; i < l; i ++, p --, dw *= 10) {
        if(*p < '0' || *p > '9')    return FALSE;
        dwVal += (*p - '0') * dw;
    }
    return TRUE;    
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
static BOOL Hex2Num(char * psz, DWORD & dwVal)
{
    char * p = psz;
                   
    int l = strlen(p);
    if(l == 0)  return FALSE;
                              
    DWORD dw = 1;                              
    dwVal = 0;      
    p += l - 1;
    for(int i = 0; i < l; i ++, p --, dw *= 16) {
        if(*p >= '0' && *p <= '9')  dwVal += (*p - '0') * dw;
        else if(*p >= 'a' && *p <= 'f') dwVal += (*p - 'a' + 10) * dw;
        else if(*p >= 'A' && *p <= 'F') dwVal += (*p - 'A' + 10) * dw;
        else    return FALSE;
    }
    return TRUE;    
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL Str2Num(char * psz, DWORD & dwVal)
{
    char * p = SkipHeadWS(psz);

    CutTailWS(p);                   
                 
    if(*p == '0' && (*(p+1) == 'x' || *(p+1) == 'X')) {
        p += 2;
        return  Hex2Num(p, dwVal);
    }                               
    else return Dec2Num(p, dwVal);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void DrawBitmap(CBitmap * bmp, CRect &rect, CDC * pDC)
{
    CDC dc;
    dc.CreateCompatibleDC(pDC);
    CBitmap * bmpOld = dc.SelectObject(bmp);
    pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),
        &dc, 0, 0, SRCCOPY);
    dc.SelectObject(bmpOld);    
} 

/////////////////////////////////////////////////////////////////////////////
// Save/Restore window Position & size

static char BASED_CODE szSection[] = "WindowPos";
static char * szWindowPos[] = {
    // sorted by window ID
    "MainFrame",    
    "CPU",
    "Shell",
    "Trace",
    "Memory1",          
    "Memory2",
    "Memory3",
    "Source",
    "Stack",
    "Variable",
    "Bit Memory",
    "Peripheral"    
};    
static char szFormat[] = "%d %u,%u,%d,%d,%d,%d,%d,%d,%d,%d";

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL ReadWindowPlacement(int nWID, LPWINDOWPLACEMENT pwp, BOOL &isOpened)
{
    CString strBuffer = AfxGetApp()->
        GetProfileString(szSection, szWindowPos[nWID]);
    if (strBuffer.IsEmpty())
        return FALSE;

    WINDOWPLACEMENT wp;                  
    int nOpened;
    int nRead = sscanf(strBuffer, szFormat, &nOpened,
        &wp.flags, &wp.showCmd,
        &wp.ptMinPosition.x, &wp.ptMinPosition.y,
        &wp.ptMaxPosition.x, &wp.ptMaxPosition.y,
        &wp.rcNormalPosition.left, &wp.rcNormalPosition.top,
        &wp.rcNormalPosition.right, &wp.rcNormalPosition.bottom);

    if (nRead != 11)
        return FALSE;

    wp.length = sizeof wp;
    *pwp = wp;     
    isOpened = nOpened;
    return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void WriteWindowPlacement(int nWID, LPWINDOWPLACEMENT pwp, BOOL isOpened)
    // write a window placement to settings section of app's ini file
{
    char szBuffer[100];
    
    sprintf(szBuffer, szFormat, isOpened,
        pwp->flags, pwp->showCmd,
        pwp->ptMinPosition.x, pwp->ptMinPosition.y,
        pwp->ptMaxPosition.x, pwp->ptMaxPosition.y,
        pwp->rcNormalPosition.left, pwp->rcNormalPosition.top,
        pwp->rcNormalPosition.right, pwp->rcNormalPosition.bottom);

    AfxGetApp()->WriteProfileString(szSection, szWindowPos[nWID], szBuffer);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void SaveWindowPlacement(void)
{
    WINDOWPLACEMENT wp;
    CWnd * pWnd;
    BOOL isOpened;

    wp.length = sizeof wp;          
    
    // Save Mainframe
    for(int i = 0; i < WID_COUNT; i ++) {
        if(i == WID_MAIN) { 
            pWnd = AfxGetApp()->m_pMainWnd;
            isOpened = TRUE;
        } else if(i == WID_CPU) {
            pWnd = pCpuWnd;
            isOpened = isCpuOn;
        } else if(i == WID_PERI) {
            pWnd = pPeriWnd;
            isOpened = isPeriOn;
        } else if(i == WID_SHELL) {
            pWnd = pShellWnd;
            isOpened = isShellOn;
        } else if(i == WID_TRACE) {
            pWnd = pTraceWnd;
            isOpened = isTraceOn;
        } else if(i == WID_MEMORY) {
            pWnd = pMemWnd[0];
            isOpened = isMemOn[0];
        } else if(i == WID_MEM2) {
            pWnd = pMemWnd[1];
            isOpened = isMemOn[1];
        } else if(i == WID_MEM3) {
            pWnd = pMemWnd[2];
            isOpened = isMemOn[2];
        } else if(i == WID_SOURCE) {
            pWnd = pSourceWnd;
            isOpened = isSourceOn;
        } else if(i == WID_STACK) {
            pWnd = pStackWnd;
            isOpened = isStackOn;
        } else if(i == WID_VARIABLE) {
            pWnd = pVariableWnd;
            isOpened = isVariableOn;
        } else if(i == WID_BMEM) {
            pWnd = pBMemWnd;
            isOpened = isBMemOn;
        } 
        if(isOpened && pWnd->GetWindowPlacement(&wp))
        {
            wp.flags = 0;
            if (pWnd->IsZoomed())
                wp.flags |= WPF_RESTORETOMAXIMIZED;
        }
        WriteWindowPlacement(i, &wp, isOpened);
    }
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL RestoreWindowPlacement(void)
{
    WINDOWPLACEMENT wp;
    CWnd * pWnd;
    BOOL isOpened;
    BOOL isInit = FALSE;

    wp.length = sizeof wp;          
    
    // Save Mainframe
    for(int i = 0; i < WID_COUNT; i ++) {
        if(!ReadWindowPlacement(i, &wp, isOpened) || !isOpened) continue;
        isInit = TRUE;
        if(i == WID_MAIN) { 
            pWnd = AfxGetApp()->m_pMainWnd;
        } else if(i == WID_CPU) {
            CpuOpenWindow((CMDIFrameWnd *)(AfxGetApp()->m_pMainWnd), TRUE);
            pWnd = pCpuWnd;      
        } else if(i == WID_PERI) {
            PeriOpenWindow((CMDIFrameWnd *)(AfxGetApp()->m_pMainWnd));
            pWnd = pPeriWnd;      
        } else if(i == WID_SHELL) {
            ShlOpenWindow((CMDIFrameWnd *)(AfxGetApp()->m_pMainWnd), TRUE);
            pWnd = pShellWnd;
        } else if(i == WID_TRACE) {
            TrcOpenWindow((CMDIFrameWnd *)(AfxGetApp()->m_pMainWnd));
            pWnd = pTraceWnd;
        } else if(i == WID_MEMORY) {
            NewMemoryOpenWindow((CMDIFrameWnd *)(AfxGetApp()->m_pMainWnd), 0);
            pWnd = pMemWnd[0];
        } else if(i == WID_MEM2) {
            NewMemoryOpenWindow((CMDIFrameWnd *)(AfxGetApp()->m_pMainWnd), 1);
            pWnd = pMemWnd[1];
        } else if(i == WID_MEM3) {
            NewMemoryOpenWindow((CMDIFrameWnd *)(AfxGetApp()->m_pMainWnd), 2);
            pWnd = pMemWnd[2];
        } else if(i == WID_SOURCE) {
            SrcOpenWindow(TRUE, (CMDIFrameWnd *)(AfxGetApp()->m_pMainWnd), 
                TRUE);
            pWnd = pSourceWnd;
        } else if(i == WID_STACK) {
            StkOpenWindow((CMDIFrameWnd *)(AfxGetApp()->m_pMainWnd));
            pWnd = pStackWnd;
        } else if(i == WID_VARIABLE) {
            VarOpenWindow((CMDIFrameWnd *)(AfxGetApp()->m_pMainWnd));
            pWnd = pVariableWnd;
        } else if(i == WID_BMEM) {
            BMemOpenWindow((CMDIFrameWnd *)(AfxGetApp()->m_pMainWnd));
            pWnd = pBMemWnd;
        } 
        pWnd->SetWindowPlacement(&wp);
        if(i != WID_MAIN)    
            ((CMDIChildWnd *)pWnd)->MDIActivate();
    }             
        
    return isInit;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Create Menu Check BMP -- A Circular Point
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL CreateMenuCheckBMP(void)
{
    DWORD dw = GetMenuCheckMarkDimensions();
    unsigned wd = LOWORD(dw);
    unsigned ht = HIWORD(dw);
    CRect rc(CPoint(0,0), CSize(wd, ht));                          
    CBrush br(PALETTEINDEX(COLOR_WHITE)), * brOld;
    
    CDC dc;
    if(!dc.CreateIC("DISPLAY", NULL, NULL, NULL))  return FALSE;
    
    CDC dc1;
    if(!dc1.CreateCompatibleDC(&dc))    return FALSE;
    if(!bmpMenuCheck.CreateCompatibleBitmap(&dc1, wd, ht)) return FALSE;
    if(!bmpMenuUncheck.CreateCompatibleBitmap(&dc1, wd, ht)) return FALSE;
    
    CBitmap * pOld = dc1.SelectObject(&bmpMenuCheck);
                              
    dc1.FillRect(rc, &br);
                           
    CRect rc1;
    rc1.left = (wd - 5) / 2;
    rc1.top = (ht - 5) / 2;
    rc1.right = rc1.left + 5;
    rc1.bottom = rc1.top + 5;
    
    dc1.Ellipse(rc1);    
    brOld = (CBrush *)(dc1.SelectStockObject(BLACK_BRUSH));
    dc1.FloodFill(wd / 2, ht / 2, PALETTEINDEX(COLOR_BLACK)); 
    dc1.SelectObject(brOld);
    
    dc1.SelectObject(&bmpMenuUncheck);
                              
    dc1.FillRect(rc, &br);
                         

    dc1.SelectObject(pOld);
    
    dc1.DeleteDC();
    dc.DeleteDC();

    return TRUE;    
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void DeleteMenuCheckBMP(void)
{
    bmpMenuCheck.DeleteObject();
    bmpMenuUncheck.DeleteObject();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void SetMainMenuCheck(CMenu & menu) 
{
    menu.SetMenuItemBitmaps(ID_OPTIONS_UNTILCALL, MF_BYCOMMAND, 
        &bmpMenuUncheck, &bmpMenuCheck);
    menu.SetMenuItemBitmaps(ID_OPTIONS_INTOCALL, MF_BYCOMMAND, 
        &bmpMenuUncheck, &bmpMenuCheck);
    menu.SetMenuItemBitmaps(ID_OPTIONS_UNTILRETURN, MF_BYCOMMAND, 
        &bmpMenuUncheck, &bmpMenuCheck);
    menu.SetMenuItemBitmaps(ID_OPTIONS_OVERRETURN, MF_BYCOMMAND, 
        &bmpMenuUncheck, &bmpMenuCheck);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Mark PC line in the source window
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void MarkPC(void)
{
	// Added by Chen, 06/05/96.
	// Return if EP is not halt.
	unsigned char uchStatus;
	if ( FALSE == ::GetCpuStatus(uchStatus) ) {
		return;
	}
	else if ( STATUS_HALT != uchStatus && STATUS_GOMONI != uchStatus ) {
		return;
	}
	

    if(isSourceOn)  pSourceWnd->SendMessage(XM_SRCSHOWPC);
    if(isBrowseOn)  pBrowseWnd->SendMessage(XM_SRCSHOWPC);
}                    
                    
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Update source window
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void RepaintSource(void)
{
	// Added by Chen, 06/05/96.
	// Return if EP is not halt.
	unsigned char uchStatus;
	if ( FALSE == ::GetCpuStatus(uchStatus) ) {
		return;
	}
	else if ( STATUS_HALT != uchStatus && STATUS_GOMONI != uchStatus ) {
		return;
	}
	

    if(isSourceOn)     pSourceWnd->SendMessage(XM_REPAINT);
    if(isBrowseOn)     pBrowseWnd->SendMessage(XM_REPAINT);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Uodate CPU window
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void RepaintCPU(void)
{
	// Added by Chen, 06/05/96.
	// Return if EP is not halt.
	unsigned char uchStatus;
	if ( FALSE == ::GetCpuStatus(uchStatus) ) {
		return;
	}
	else if ( STATUS_HALT != uchStatus && STATUS_GOMONI != uchStatus ) {
		return;
	}
	

    if(isCpuOn)     pCpuWnd->SendMessage(XM_REPAINT);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Update memory window
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void RepaintMemory(void)
{
	// Added by Chen, 06/05/96.
	// Return if EP is not halt.
	unsigned char uchStatus;
	if ( FALSE == ::GetCpuStatus(uchStatus) ) {
		return;
	}
	else if ( STATUS_HALT != uchStatus && STATUS_GOMONI != uchStatus ) {
		return;
	}
	

    if(isMemOn[0])     pMemWnd[0]->SendMessage(XM_REPAINT);
    if(isMemOn[1])     pMemWnd[1]->SendMessage(XM_REPAINT);
    if(isMemOn[2])     pMemWnd[2]->SendMessage(XM_REPAINT);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Update bit memory window
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void RepaintBMemory(void)
{
	// Added by Chen, 06/05/96.
	// Return if EP is not halt.
	unsigned char uchStatus;
	if ( FALSE == ::GetCpuStatus(uchStatus) ) {
		return;
	}
	else if ( STATUS_HALT != uchStatus && STATUS_GOMONI != uchStatus ) {
		return;
	}
	

    //if(isBMemOn)     pBMemWnd->SendMessage(XM_REPAINT);
    if(isBMemOn)     //pBMemWnd->Invalidate();
      ((CBMemoryWindow*)pBMemWnd)->RepaintBitWnd();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Update trace window
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void RepaintTrace(void)
{
	// Added by Chen, 06/05/96.
	// Return if EP is not halt.
	unsigned char uchStatus;
	if ( FALSE == ::GetCpuStatus(uchStatus) ) {
		return;
	}
	else if ( STATUS_HALT != uchStatus && STATUS_GOMONI != uchStatus ) {
		return;
	}
	

    if(isTraceOn)     pTraceWnd->SendMessage(XM_REPAINT);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Update stack window
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void RepaintStack(void)
{
	// Added by Chen, 06/05/96.
	// Return if EP is not halt.
	unsigned char uchStatus;
	if ( FALSE == ::GetCpuStatus(uchStatus) ) {
		return;
	}
	else if ( STATUS_HALT != uchStatus && STATUS_GOMONI != uchStatus ) {
		return;
	}
	

//    if(isStackOn)     pStackWnd->SendMessage(XM_REPAINT);
    extern void StkUpdateStackWindow(BOOL bUpdateStackOnly = FALSE);
    if(isStackOn)   StkUpdateStackWindow();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Update peripheral window
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void RepaintPeri(void)
{
	// Added by Chen, 06/05/96.
	// Return if EP is not halt.
	unsigned char uchStatus;
	if ( FALSE == ::GetCpuStatus(uchStatus) ) {
		return;
	}
	else if ( STATUS_HALT != uchStatus && STATUS_GOMONI != uchStatus ) {
		return;
	}
	

	void FreshPer(void);

    if(isPeriOn)
	    FreshPer();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Update variable window
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void RepaintVariable(void)
{
	// Added by Chen, 06/05/96.
	// Return if EP is not halt.
	unsigned char uchStatus;
	if ( FALSE == ::GetCpuStatus(uchStatus) ) {
		return;
	}
	else if ( STATUS_HALT != uchStatus && STATUS_GOMONI != uchStatus ) {
		return;
	}
	

//    if (isVariableOn)   pVariableWnd->SendMessage(XM_REPAINT);
    extern void VarUpdateWholeWindow(void);
    if(isVariableOn)    VarUpdateWholeWindow();
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Called after an emulation operation
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void OnEmulation(void)
{
	// Added by Chen, 06/21/96.
	// Close the SPA window at once.
	if ( ::pSpaCodeWnd ) {
		::CloseCodeCoverageWindow();
	}
	
	// Added by Chen, 06/05/96.
	// Return if EP is not halt.
	unsigned char uchStatus;
	if ( FALSE == ::GetCpuStatus(uchStatus) ) {
		return;
	}
	else if ( STATUS_HALT != uchStatus && STATUS_GOMONI != uchStatus ) {
		return;
	}
	

	void FreshPer(void);


    RepaintCPU();
    if(isSourceOn){
//       pSourceWnd->Invalidate();                          
       pSourceWnd->RedrawWindow(NULL,NULL,RDW_INVALIDATE|RDW_UPDATENOW);
       pSourceWnd->SendMessage(XM_SRCSHOWPC);
    }   
    RepaintBMemory();
    if(IsRunAccess())    RepaintMemory();
    RepaintVariable();
    RepaintStack();
    RepaintTrace();
    //RepaintPeri();
    FreshPer();
}

void RepaintWindows(void)
{
	// Added by Chen, 06/05/96.
	// Return if EP is not halt.
	unsigned char uchStatus;
	if ( FALSE == ::GetCpuStatus(uchStatus) ) {
		return;
	}
	else if ( STATUS_HALT != uchStatus && STATUS_GOMONI != uchStatus ) {
		return;
	}
	

	void FreshPer(void);

    //if(isSourceOn)  pSourceWnd->SendMessage(XM_SRCSHOWPC);
    RepaintSource();
    RepaintCPU();
    RepaintBMemory();
    if(IsRunAccess())    RepaintMemory();
    RepaintVariable();
    RepaintStack();
    RepaintTrace();
    //RepaintPeri();
    FreshPer();
}


/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void TestMessage(void)
{
    MSG message;
    DWORD dwTemp = ::GetTickCount();
    while ( ::PeekMessage(&message, NULL, 0, 0, PM_REMOVE) &&  (dwTemp+250) > GetTickCount() ) {
        ::TranslateMessage(&message);
        ::DispatchMessage(&message);
    }
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: Check message in the message queue until no more messages
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL CheckMessage(void)
{
    MSG msg;
    
    while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
        if(msg.message == WM_QUIT)
            return FALSE;
        else {
            ::TranslateMessage(&msg);
            ::DispatchMessage(&msg);
        }
    }
    return TRUE;
}

void ExitEpsld(void)
{
    AfxMessageBox("Communication Failure!!!");

    //AfxGetApp()->m_pMainWnd->SendMessage(WM_QUIT);
    AfxAbort();
}

void SetCurLoadPath(int flag)
{
    CString strPath="";
    char path_buffer[_MAX_PATH];
    char drive[_MAX_DRIVE];
    char dir[_MAX_DIR];
    char path_buffer2[_MAX_PATH];
    if(flag)
       strPath = ::szAppPath;
    else{
	   strPath = AfxGetApp()->GetProfileString("Source Path", "Path1");
	   if(_stricmp(strPath,"")==0) return; 
	}
	
	if(strPath.GetLength() > _MAX_PATH) return ;
	strcpy(path_buffer, strPath);
	_splitpath( path_buffer, drive, dir, NULL, NULL );
    _makepath(path_buffer2, drive, dir, NULL, NULL);
    
    _chdrive(toupper(path_buffer2[0])-'A'+1);
    _chdir(path_buffer2);                   
    return ;     
}
///////////////////////(EOF)/////////////////////////////////////////////////                               
