/****************************************************************************
**
**  Name:  whptexec.c
**
**  Description:
**     Server and presenter for Watch Breakpoint
**
**  Status:  TESTED
**
**  $Log:   S:/tbird/arcppc/bkptexec/whptexec.c_v  $
** 
**    Rev 1.15   03 Feb 1998 15:10:50   kevin
** Set selection when input is invaild in edit box
** 
**    Rev 1.14   19 Jan 1998 11:25:42   kevin
** allow IW2 and IW3 to be used as breakpoints
** 
**    Rev 1.13   23 Dec 1997 10:20:14   kevin
** modified error check for LWatchpoint settings
** 
**    Rev 1.12   01 Dec 1997 16:13:38   kevin
** removed redundant statements
** 
**    Rev 1.11   20 Nov 1997 13:47:18   kevin
** Fine tune UI
** 
**    Rev 1.10   18 Nov 1997 12:46:32   kevin
** Too many fixes. The biggest change is to prevent from dangle setting.
** 
**    Rev 1.9   07 Nov 1997 17:15:40   kevin
** 1. ESC key will close dialog box.
** 2. Function keys will be sent to main tool bar
** 
**    Rev 1.8   05 Nov 1997 12:12:30   kevin
** Watchpoint windows with thickframe
** 
**    Rev 1.7   26 Sep 1997 11:27:54   kevin
** The default of access size should be ACCESS_WORD (1)
** 
**    Rev 1.6   19 Sep 1997 16:33:28   kevin
** added shell commands
** 
**    Rev 1.5   17 Sep 1997 18:32:12   kevin
** 
**    Rev 1.4   17 Sep 1997 15:53:34   kevin
** 
**    Rev 1.3   12 Sep 1997 15:43:10   kevin
** Underconstruction
**
**  $Header:   S:/tbird/arcppc/bkptexec/whptexec.c_v   1.15   03 Feb 1998 15:10:50   kevin  $
**
**  Copyright (C) 1997 Microtek International.  All rights reserved.
**
*****************************************************************************/
                /************************
                *                       *
                *   INCLUDE FILE        *
                *                       *
                *************************/

#ifndef __WINDOW_H
#include "windows.h"
#endif

#include <commdlg.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>

#ifndef _BASEWIND_
#include "basewind.h"   /* basetype */
#endif

#ifndef _HOSTERRS_
#include "hosterrs.h"
#endif

#ifndef _CLIULIB_
#include "cliulib.h"
#endif

#ifndef _CLISRV_
#include "clisrv.h"
#endif

#ifndef _HEAP_
#include "heap.h"
#endif

#ifndef _EVENT_
#include "event.h"
#endif

#ifndef _WHPTEXEC_
#include "whptexec.h"
#endif

#ifndef _WHPT_
#include "whpt.h"
#endif

#ifndef _HLPENTRY_
#include "hlpentry.h"
#endif
                /***********************
                *                      *
                *     DEFINITIONS      *
                *                      *
                ************************/
#define cOffset         3
#define rwOffset        0
#define sizeOffset      1
#define relOffset       1
#define lwOffset        1
#define cNotActive      0
#define rwNotActive     0
#define sizeNotActive   0
#define relNotActive    0
#define lwNotActive     0
#define NONACTIVE       4
#define ERR_L_ADDR_SETTING       1
#define ERR_L_DATA_SETTING       2
#define ERR_L_WATCHPOINT_SETTING 3
#define ERR_LW_INUSE             4
#define ERR_IW_INUSE_L           5
#define ERR_IW_INUSE_C           6
#define ERR_C_IW_MISS            7
#define ERR_C_LW_MISS            8

               /************************
               *                       *
               *     EXTERNAL          *
               *                       *
               *************************/
HANDLE hLib;
static HANDLE cliServerHandle = 0;       /* return address for CLI results */
               /************************
               *                       *
               *       LOCAL           *
               *                       *
               *************************/
static HANDLE hInst;
CHAR szString[128];
CHAR szAppName[20];
HWND hWndWatchPoint=NULL;
BOOL nonMaskBit=FALSE;
HMENU hMenu;
char gIWhptAddr[4][100];
char gLWhptAddr[2][100];
char gLWhptData[2][20];
char gLWhptMask[2][20];
char gCCount[2][20];
BOOL bWhptInUse[12];
BOOL bHwBkpt;

PRIVATE BOOLEAN registeredClasses = FALSE;

DESCRIPTOR theWatchPoint=NULL;
FARPROC lpIWatchPointProc,lpLWatchPointProc,lpCounterProc;
int  nTop,nLeft,cxMaxChar,cxAveChar,cyHeight;

I_WATCHPOINT gIWatchpoint;
L_ADDR gLAddr;
L_DATA gLData={{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {ACCESS_WORD,ACCESS_WORD}};
L_WATCHPOINT gLWatchpoint={{0,0}, {NONACTIVE,NONACTIVE},
                           {NONACTIVE,NONACTIVE}, {NONACTIVE,NONACTIVE}};
WATCHPOINT_COUNTER gWatchCounter;

               /************************
               *                       *
               *       PROTOTYPE       *
               *                       *
               *************************/

int  nCwRegisterClasses(VOID);
long FAR PASCAL WatchPointWndProc (HWND hWnd, UINT message,
         UINT wParam, LONG lParam);
BOOL FAR PASCAL IWatchPointProc (HWND hDlg, UINT message,
                UINT wParam, LONG lParam);
BOOL FAR PASCAL LWatchPointProc (HWND hDlg, UINT message,
                UINT wParam, LONG lParam);
BOOL FAR PASCAL CounterProc (HWND hDlg, UINT message,
                UINT wParam, LONG lParam);
RETCODE CheckIWatchpointError(HWND hDlg);
RETCODE CheckLWatchpointError(HWND hDlg);
RETCODE CheckCounterError(HWND hDlg);
RETCODE CheckAddressDataError(char *string,U32 *value,U8 flag);
RETCODE CheckMaskError(U32 mask);
RETCODE CombineDataMask(char *string,U32 mask);
RETCODE ConvertMask(U32 *mask,char *string);
RETCODE ConvertOrigMask(U32 mask,U32 *tMask);
RETCODE SetupILCombox(HWND hDlg,U8 flag);
RETCODE SetupIData(HWND hDlg);
RETCODE SetupLData(HWND hDlg);
VOID ToolBarMsg(WPARAM WParam, LPARAM LParam);

RETCODE EXPORT WhptCloseWindow();
RETCODE EXPORT WhptExistsWindow(HWND *whptHandle);
RETCODE EXPORT WhptOpenWindow(HWND parent,int left,int top,int width,
          int height,DWORD dwStyle,DWORD dwExStyle,HWND *whptWindow);

               /************************
               *                       *
               *      EXECUTE CODE     *
               *                       *
               *************************/

/**************************************************************************
**
** LibMain
**
** Description: Main entry point of the WHPTEXEC.DLL
**
**	Parameters:
**    input:
**       hInstance:     Handle of the library instance
**       wDataSeg:      Value of Data Segment register
**       cbHeapSize:    Heap Size of the heap defined in the DEF
**       lpszCmdLine:   Command Line information (rarely used)
**
**    output:
**
***************************************************************************/
#pragma argsused
int FAR PASCAL LibMain(HANDLE hInstance, WORD wDataSeg, WORD cbHeapSize,
                       LPSTR lpszCmdLine) {
                       
    /* the LIBENTRY initializes the local heap by calling LocalInit() and
       then calls LibMain.  The LocalInit() locks the data segment of the
       library when initialize; therefore LibMain needs to unlock */
    if (cbHeapSize != 0) /* the DLL Data segment is MOVEABLE */
       UnlockData(0);

    /* initialize successfully */
    hLib = hInstance;

    //ErrInitDLL(MODULE_WATCHPOINT, MODULE_NAME);  ** set up for error text **
    //err = BxInit();
    //if (GOOD != err)
    //  ErrDisplayError(err, FORCE_POPUP);

    return(TRUE);
}

/**************************************************************************
**
** InitCServer
**
***************************************************************************/
RETCODE EXPORT InitCServer(HANDLE cliHandle, HANDLE dllHandle) {
   CSERVER_NEW_REGISTRATION FAR * msgBufPtr;
   CHAR buf[20];

   cliServerHandle = cliHandle;
   msgBufPtr =
      (CSERVER_NEW_REGISTRATION FAR *)TMalloc(sizeof(CSERVER_VARIABLE_VALUE));
   if (msgBufPtr == NULL) return(ER_OUT_OF_MEMORY);
   msgBufPtr->stringResourceHandle = dllHandle;
   msgBufPtr->serverNameIndex = 30;
   msgBufPtr->dllNameIndex = 31;
   msgBufPtr->numberOfCommandsIndex = 32;
   msgBufPtr->commandStartIndex = 33;
   SendMessage(cliHandle, CLI_NEW_SVR_REGISTRATION, CLI_NEW_SVR_REGISTRATION,
      (DWORD)msgBufPtr);
   GetPrivateProfileString("SourceInfo", "HwBkpt", "1", buf,
                        sizeof(buf), "micepack.ini");
   bHwBkpt = buf[0] != '0'; //enable hardware breakpoints

   return(GOOD);
}

/*****************************************************************************
**
**  ToolBarMsg
**
*****************************************************************************/
VOID ToolBarMsg(WPARAM WParam, LPARAM LParam)   {
   HWND hToolBar;
   // Pass a message off to the toolbar window
   if (GetToolBarHandle((HANDLE FAR *) &hToolBar) == GOOD) {
      SendMessage(hToolBar, WM_COMMAND, WParam, LParam);
   }
}
/**************************************************************************
**
** WphtGetWatchpoints
**
***************************************************************************/
RETCODE EXPORT WhptGetWatchpoints(I_WATCHPOINT *iwhpt,L_ADDR *laddr,
    L_DATA *ldata,L_WATCHPOINT *lwhpt, WATCHPOINT_COUNTER *whptCounter) {
    *iwhpt=gIWatchpoint;
    *laddr=gLAddr;
    *ldata=gLData;
    *lwhpt=gLWatchpoint;
    *whptCounter=gWatchCounter;
    return GOOD;
}
/*****************************************************************************
**
**  CreateWatchPointPresenter
**
*****************************************************************************/
#pragma argsused
RETCODE CreateWatchPointPresenter(HINSTANCE hInstance, S16 left, S16 top,
                              S16 width, S16 height) {
   int nRc;  // return value from Register Classes

   strcpy(szAppName, "WatchPoint");
   hInst = hInstance;
   nTop=top;
   nLeft=left;
   if(!registeredClasses) {
      /* register window classes if first instance of application */
      if ((nRc = nCwRegisterClasses()) == -1) {
         // TODO: Replace this with ErrDisplayFormattedError
         strcpy(szString, "Error registering virtual listbox or peripheral");
         MessageBox(NULL, szString, NULL, MB_ICONEXCLAMATION);
         return nRc;
      }
      registeredClasses = TRUE;
   }

   if (!left && !width) {
      left = CW_USEDEFAULT;
      width = CW_USEDEFAULT;
   }
   
   //initialize WatchPoint server
   //if ((err=WhptWatchPointOpen(&theWatchPoint,"","default"))!=GOOD) {
   //   ErrDisplayError(err,FORCE_POPUP);
   //   return GOOD;
   //}

   /* create WatchPoint window */
   hWndWatchPoint = CreateWindow((LPSTR) szAppName,    /* Window class name    */
                           (LPSTR)"WatchPoint",  /* title         */
                           (WS_CAPTION     |     /* Title and Min/Max    */
                           WS_SYSMENU      |     /* Add system menu box  */
                           WS_MINIMIZEBOX  |     /* Add minimize box     */
                          /* WS_MAXIMIZEBOX  |      Add maximize box     */
                           WS_THICKFRAME   |
                           WS_CLIPCHILDREN |     /* don't draw in child ares */
                           WS_OVERLAPPED),
                           left, top,         
                           250, 400,
                           NULL,                 /* Parent window's handle */
                           NULL,                 /* Default to Class Menu */
                           hInst,                /* Instance of window */
                           NULL);       /* Create struct for WM_CREATE */

   UpdateWindow (hWndWatchPoint);
   return GOOD;
}

/*****************************************************************
*                                                                *
*         WatchPointWndProc                                      *
*                                                                *
******************************************************************/
long FAR PASCAL WatchPointWndProc (HWND hWnd, UINT message,
         UINT wParam, LONG lParam) {
HDC hDc;
HFONT hFont, hOldFont;
TEXTMETRIC     tm;
PAINTSTRUCT    ps;
S16 cyChar, i, nResult;
char szRel[5][14]={" ","Equal to","Less than", "Greater than","Not equal to"};
char szIWComb[12][6]={" ","A","A & B"," ","B","A | B",
                      " ","C","C & D"," ","D","C | D"};
char szReadWrite[4][12]={" ","Read/Write","Read only","Write only"};
char szSigned[2][10]={"Unsigned","Signed"};
char szSize[3][10]={"Word","Half Word","Byte"};
char szIW[5][5]={"IW0","IW1","IW2","IW3","***"};
char szLAddrComb[5][10]={"E","F","E & F","E | F","***"};
char szLDataComb[5][10]={"G","H","G & H","G | H","***"};
char szWatchPoint[4][5]={"IW0","LW0","IW1","LW1"};
char szEvent[16][12]={"A","B","C","D","IW0","IW1","IW2","IW3",
                      "E","F","G","H","LW0","LW1","Count-A","Count-B"};
char szEnable[2][10]={"Disable","Enable"};
char szBreak[2][10] ={"Disable","Break"};
char tempString[20];
static U16  tab1, tab2, tab3, tab4;
HWND hToolBar;

   switch (message) {
      case WM_CREATE:
         // clear all in-use flags, C_LW1 is the last one
         for (i=0; i<C_LW1+1; i++)
            bWhptInUse[i] = FALSE;

         // Initial all data members
         for (i=0; i<4; i++)
            gIWatchpoint.relation[i] = 0;

         // Tell the F1 Hook procedure who we are, so it doesn't
         // get confused and pop up somebody else's help...
         RegisterHelpEntry(hWnd, (LONG) HI_WATCHPOINT, HE_WATCHPOINT);

         for (i=0; i<2; i++) {
            if (gWatchCounter.ilw[i] == 0)
               gWatchCounter.ilw[i] = IW;
         }
         hDc = GetDC(hWnd);

         hFont=CreateFont(16,6,0,0,
                  FW_NORMAL,0,0,0,ANSI_CHARSET,
                  OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
                  DEFAULT_QUALITY, FIXED_PITCH|FF_ROMAN,
                  "TmsRmn");
         hOldFont=SelectObject(hDc,hFont);
         GetTextMetrics(hDc,&tm);
         cxMaxChar = tm.tmMaxCharWidth;
         cxAveChar = tm.tmAveCharWidth;
         cyChar = tm.tmHeight + 3 * tm.tmExternalLeading ;
         cyHeight = 1.4 * cyChar;
         tab1 = cxAveChar * 14;
         tab2 = cxAveChar * 32;
         tab3 = cxAveChar * 47;
         tab4 = cxAveChar * 62;
         ReleaseDC(hWnd,hDc);

         hMenu=LoadMenu(hInst, "Watchpoint_Menu");
         SetMenu(hWnd,hMenu);

         MoveWindow(hWnd,nTop,nLeft,90*cxAveChar,
            20*cyHeight,1);

         CheckMenuItem(hMenu, IDM_NONMASK_BIT,
                       (nonMaskBit)?MF_CHECKED:MF_UNCHECKED);
         Sds2AbiFwSetBkptNonmask((U16)nonMaskBit);
         CheckMenuItem(hMenu, IDM_ENABLEHWBKPT,
                       (bHwBkpt)?MF_CHECKED:MF_UNCHECKED);
         return 0;

      case WM_KEYUP:
         switch(wParam) {
            case VK_F1: /* let the Hook Procedure handle it */
               WinHelp(hWnd, "PWRVIEWS.HLP", HELP_CONTEXT, HE_WATCHPOINT);
               break;
            case VK_F2:
            case VK_F3:
            case VK_F4:
            case VK_F5:
            case VK_F6:
            case VK_F7:
            case VK_F8:
            case VK_F9:
            case VK_F10:
            case VK_F11:
            case VK_F12:
               if ((GetToolBarHandle((HANDLE FAR *) &hToolBar) == GOOD) &&
                   (hToolBar != NULL)) {
                  SendMessage(hToolBar, WM_KEYDOWN, wParam, lParam);
               }
               break;
            default:
               return DefWindowProc(hWnd, message, wParam, lParam);
         }
         return TRUE;

      case WM_COMMAND:
         switch(wParam) {
            case IDM_MENU_EXIT:
               PostMessage(hWnd, WM_CLOSE, 0, 0L);
               break;

            case IDM_IWATCHPOINT:
               lpIWatchPointProc=MakeProcInstance((FARPROC)IWatchPointProc,
                    hInst);
               nResult=DialogBox(hInst,"IWatchpoint",hWnd,lpIWatchPointProc);
               InvalidateRect(hWnd,NULL,TRUE);
               UpdateWindow(hWnd);
               return 0;

            case IDM_LWATCHPOINT:
               lpLWatchPointProc=MakeProcInstance((FARPROC)LWatchPointProc,
                     hInst);
               nResult=DialogBox(hInst,"LWatchpoint",hWnd,lpLWatchPointProc);
               InvalidateRect(hWnd,NULL,TRUE);
               UpdateWindow(hWnd);
               return 0;

            case IDM_COUNTER:
               lpCounterProc=MakeProcInstance((FARPROC)CounterProc,
                     hInst);
               nResult=DialogBox(hInst,"Counter",hWnd,lpCounterProc);
               InvalidateRect(hWnd,NULL,TRUE);
               UpdateWindow(hWnd);
               return 0;

            case IDM_EVTWBKPT:
               ToolBarMsg(MENU_OFFSET + BREAKPOINT_WINDOW, lParam);
               break;
            case IDM_EVTWCPU:
               ToolBarMsg(MENU_OFFSET + CPU_WINDOW, lParam);
               break;
            case IDM_EVTWMEMORY:
               ToolBarMsg(MENU_OFFSET + MEMORY_WINDOW, lParam);
               break;
            case IDM_EVTWPERIPHERAL:
               ToolBarMsg(MENU_OFFSET + PERIPHERAL_WINDOW, lParam);
               break;
            case IDM_EVTWSHELL:
               ToolBarMsg(MENU_OFFSET + SHELL_WINDOW, lParam);
               break;
            case IDM_EVTWSOURCE:
               ToolBarMsg(MENU_OFFSET + SOURCE_WINDOW, lParam);
               break;
            case IDM_EVTWSTACK:
               ToolBarMsg(MENU_OFFSET + STACK_WINDOW, lParam);
               break;
            case IDM_EVTWSTATUS:
               ToolBarMsg(MENU_OFFSET + STATUS_WINDOW, lParam);
               break;
            case IDM_EVTWWATCHPOINT:
               ToolBarMsg(MENU_OFFSET + WATCHPOINT_WINDOW, lParam);
               break;
            case IDM_EVTWTOOLBAR:
               ToolBarMsg(MENU_OFFSET + TOOLBAR_WINDOW, lParam);
               break;
            case IDM_EVTWVARIABLE:
               ToolBarMsg(MENU_OFFSET + VARIABLE_WINDOW, lParam);
               break;
            case IDM_BREAKPOINT:
               Sds2AbiFwLoadWatchpoints(gIWatchpoint,gLAddr,gLData,
                  gLWatchpoint,gWatchCounter);
               break;
            case IDM_NONMASK_BIT:
               nonMaskBit = !nonMaskBit;
               CheckMenuItem(hMenu, IDM_NONMASK_BIT,
                             (nonMaskBit)?MF_CHECKED:MF_UNCHECKED);
               Sds2AbiFwSetBkptNonmask((U16)nonMaskBit);
               break;

            case IDM_ENABLEHWBKPT:
               bHwBkpt = !bHwBkpt;
               CheckMenuItem(hMenu, IDM_ENABLEHWBKPT,
                     (bHwBkpt)?MF_CHECKED:MF_UNCHECKED);
               WritePrivateProfileString("SourceInfo", "HwBkpt",
                     bHwBkpt?"1":"0", "micepack.ini");
               if (bHwBkpt)
                  gIWatchpoint.enable[2] = gIWatchpoint.enable[3] = 0;

               InvalidateRect(hWnd,NULL,TRUE);
               UpdateWindow(hWnd);
               break;

            case IDM_HELP:
               WinHelp(hWnd, "PWRVIEWS.HLP", HELP_CONTEXT, HE_CONTENTS);
               break;
            case IDM_HLPHLP:
               WinHelp(hWnd, "PWRVIEWS.HLP", HELP_HELPONHELP, HE_CONTENTS);
               break;
            case IDM_HLPWHPT:
               WinHelp(hWnd, "PWRVIEWS.HLP", HELP_CONTEXT, HE_WATCHPOINT);
               break;
         }
         break;
      case WM_PAINT :
         hDc=BeginPaint(hWnd,&ps);
         //item name
         for (i=0;i<16;i++)
            TextOut(hDc,1.5*cxAveChar,cyHeight*(1+i),szEvent[i],
               strlen(szEvent[i]));
         //A, B, C, D -CONDITION, ADDRESS
         for (i=0;i<4;i++) {
            if (bHwBkpt && (i==2 || i==3))
               continue;

            if (gIWatchpoint.condition[i]!=0) {
               TextOut(hDc,tab1,cyHeight*(1+i),szRel[gIWatchpoint.condition[i]-cOffset],
                  strlen(szRel[gIWatchpoint.condition[i]-cOffset]));
               TextOut(hDc,tab2,cyHeight*(1+i),gIWhptAddr[i],
                  strlen(gIWhptAddr[i]));
            }
            else
               TextOut(hDc,tab1,cyHeight*(1+i),szEnable[0],
                  strlen(szEnable[0]));  // disable
         }
         //IW0,IW1,IW2,IW3-enable, relation
         for (i=0;i<4;i++) {
            if (bHwBkpt && (i==2 || i==3))
               continue;
            TextOut(hDc,tab1,cyHeight*(5+i),szBreak[gIWatchpoint.enable[i]],
               strlen(szBreak[gIWatchpoint.enable[i]]));
            if (gIWatchpoint.relation[i]) {
               TextOut(hDc,tab2,cyHeight*(5+i),szIWComb[gIWatchpoint.relation[i]-relOffset+3*i],
                  strlen(szIWComb[gIWatchpoint.relation[i]-relOffset+3*i]));
            }
         }
         //E,F-enable,condition,address,r/w
         for (i=0;i<2;i++) {
            if (gLAddr.condition[i]!=0) {
               TextOut(hDc,tab1,cyHeight*(9+i),szRel[gLAddr.condition[i]-cOffset],
                  strlen(szRel[gLAddr.condition[i]-cOffset]));
               TextOut(hDc,tab2,cyHeight*(9+i),szReadWrite[gLAddr.rw[i]-rwOffset],
                  strlen(szReadWrite[gLAddr.rw[i]-rwOffset]));
               TextOut(hDc,tab3,cyHeight*(9+i),gLWhptAddr[i],
                  strlen(gLWhptAddr[i]));
            }
            else
               TextOut(hDc,tab1,cyHeight*(9+i),szEnable[0],
                  strlen(szEnable[0]));

         }
         //G,H-enable,condition,signed,data+mask,size
         for (i=0;i<2;i++) {
            if (gLData.condition[i]!=0){
               TextOut(hDc,tab1,cyHeight*(11+i),szRel[gLData.condition[i]-cOffset],
                  strlen(szRel[gLData.condition[i]-cOffset]));
               TextOut(hDc,tab2,cyHeight*(11+i),szSigned[gLData.sign[i]],
                  strlen(szSigned[gLData.sign[i]]));
               wsprintf(tempString,"0x%lX",gLData.data[i]);
               CombineDataMask(tempString,gLData.mask[i]);
               TextOut(hDc,tab3,cyHeight*(11+i),tempString,
                  strlen(tempString));
               TextOut(hDc,tab4+30,cyHeight*(11+i),szSize[gLData.size[i]-sizeOffset],
                  strlen(szSize[gLData.size[i]-sizeOffset]));
            }
            else
               TextOut(hDc,tab1,cyHeight*(11+i),szEnable[0],
                  strlen(szEnable[0]));
         }
         //LW0,LW1-IW, L-ADDR, L-DATA
         for (i=0;i<2;i++) {
            TextOut(hDc,tab1,cyHeight*(13+i),szBreak[gLWatchpoint.enable[i]],
               strlen(szBreak[gLWatchpoint.enable[i]]));
            TextOut(hDc,tab2,cyHeight*(13+i),szIW[gLWatchpoint.iw[i]],
               strlen(szIW[gLWatchpoint.iw[i]]));
            TextOut(hDc,tab3,cyHeight*(13+i),szLAddrComb[gLWatchpoint.laddr[i]],
               strlen(szLAddrComb[gLWatchpoint.laddr[i]]));
            TextOut(hDc,tab4,cyHeight*(13+i),szLDataComb[gLWatchpoint.ldata[i]],
               strlen(szLDataComb[gLWatchpoint.ldata[i]]));
         }
         //COUNTA,COUNTB-enable,count,iw,lw
         for (i=0;i<2;i++) {
            if (gWatchCounter.enable[i]==1) {
               TextOut(hDc,tab1,cyHeight*(15+i),szBreak[gWatchCounter.enable[i]],
                  strlen(szBreak[gWatchCounter.enable[i]]));
               ultoa(gWatchCounter.count[i],tempString,10);
               TextOut(hDc,tab2,cyHeight*(15+i),tempString,
                  strlen(tempString));
               TextOut(hDc,tab3,cyHeight*(15+i),szWatchPoint[gWatchCounter.ilw[i]-1+i*2],
                  strlen(szWatchPoint[gWatchCounter.ilw[i]-1+i*2]));
            }
            else
               TextOut(hDc,tab1,cyHeight*(15+i),szEnable[0],
                  strlen(szEnable[0]));
         }
         EndPaint(hWnd,&ps);
         return 0;

      case WM_CLOSE:
         DestroyWindow(hWnd);
         hWndWatchPoint=NULL;
         break;

      case WM_DESTROY :
         hWndWatchPoint=NULL;
         break;
   }
   return DefWindowProc (hWnd, message, wParam, lParam);
}

/*****************************************************************************
**
**  nCwRegisterClasses
**
*****************************************************************************/
int nCwRegisterClasses(VOID) {
   WNDCLASS   wndclass;    /* struct to define a window class */
   HINSTANCE  hInstance;
   HWND hToolBar;
   memset(&wndclass, 0x00, sizeof(WNDCLASS));

   if (GetToolBarHandle((HANDLE FAR *) &hToolBar) == GOOD) {
      hInstance = ((HINSTANCE) GetWindowWord(hToolBar, GWW_HINSTANCE));
      wndclass.hIcon = LoadIcon(hInstance, "WATCHPOINT");
   }
   /* load WNDCLASS with window's characteristics */
   wndclass.style = CS_HREDRAW | CS_VREDRAW; // | CS_BYTEALIGNWINDOW;
   wndclass.lpfnWndProc = WatchPointWndProc;

   /* Extra storage for Class and Window objects  */
   wndclass.cbClsExtra = 0;
   wndclass.cbWndExtra = 0;
   wndclass.hInstance = hInst;
   wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);

   /* Create brush for erasing background */
   wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
   wndclass.lpszMenuName = NULL;   /* Menu Name is App Name */
   wndclass.lpszClassName = szAppName; /* Class Name is App Name */
   if(!RegisterClass(&wndclass))
      return -1;
   return(0);
}
/*****************************************************************************
**
**  WhptOpenWindow
**
*****************************************************************************/
#pragma argsused
RETCODE EXPORT WhptOpenWindow(HWND parent,int left,int top,int width,
     int height,DWORD dwStyle,DWORD dwExStyle,HWND *whptWindow) {
RETCODE err=GOOD;

   if (hWndWatchPoint == NULL) {
      err = CreateWatchPointPresenter(hLib, left, top,
               width, height);
      *whptWindow = hWndWatchPoint;
   }
   return err;
}
/*****************************************************************************
**
**  WhptCloseWindow
**
*****************************************************************************/
RETCODE EXPORT WhptCloseWindow() {
   if (hWndWatchPoint != NULL) {
      //WhptWatchPointClose(theWatchPoint);
      hWndWatchPoint = NULL;
   }
   return GOOD;
}
/*****************************************************************************
**
**  WhptExistsWindow
**
*****************************************************************************/
RETCODE EXPORT WhptExistsWindow(HWND *whptHandle) {
   *whptHandle = hWndWatchPoint;
   return GOOD;
}

/***************************************************************
**
**            IWatchPointProc
**
****************************************************************/
BOOL FAR PASCAL IWatchPointProc (HWND hDlg, UINT message,
                UINT wParam, LONG lParam) {
int i;
DWORD dwValue,dwSel;
RETCODE err;
char tempString[20];
U32 ulAddr;

   switch(message) {
      case WM_INITDIALOG:
         SetupILCombox(hDlg,0);
         SetupIData(hDlg);

         for (i=2; i<4; i++) {
            EnableWindow(GetDlgItem(hDlg,IDC_I_A_CONDITION+i*10),!bHwBkpt);
            EnableWindow(GetDlgItem(hDlg,IDC_I_A_ADDRESS+i*10),!bHwBkpt);
            EnableWindow(GetDlgItem(hDlg,IDC_I_IW0_BREAK+i*10),!bHwBkpt);
            EnableWindow(GetDlgItem(hDlg,IDC_I_IW0_RELATION+i*10),!bHwBkpt);
         }
         return TRUE;

      case WM_COMMAND:
         switch(wParam) {
            case IDC_I_A_ADDRESS:
            case IDC_I_B_ADDRESS:
            case IDC_I_C_ADDRESS:
            case IDC_I_D_ADDRESS:
               if (HIWORD(lParam)==EN_KILLFOCUS) {
                  tempString[0]='\0';
                  SendMessage(GetDlgItem(hDlg,wParam),WM_GETTEXT,
                     sizeof(tempString),(LPARAM)(LPSTR)tempString);
                  if (tempString[0]!='\0') {
                     if ((err=ConvTextToU32(tempString,&ulAddr,1))!=GOOD) {
                        ErrDisplayError(err,FORCE_POPUP);
                        SetFocus(GetDlgItem(hDlg,wParam));
                        SendMessage(GetDlgItem(hDlg,wParam), EM_SETSEL, 0, 0xFFFF0000);
                        return TRUE;
                      }
                      wsprintf(tempString,"0x%lX",ulAddr);
                      SendMessage(GetDlgItem(hDlg,wParam),WM_SETTEXT,
                          sizeof(tempString),(LPARAM)(LPSTR)tempString);
                   }
               }
               return TRUE;

            case IDC_I_IW0_BREAK:
            case IDC_I_IW1_BREAK:
            case IDC_I_IW2_BREAK:
            case IDC_I_IW3_BREAK:
               if (HIWORD(lParam)==BN_CLICKED) {
                  dwValue=!SendDlgItemMessage(hDlg,wParam,BM_GETCHECK,0,0);
                  SendDlgItemMessage(hDlg,wParam,BM_SETCHECK,dwValue,0);
               }
               return TRUE;

            case IDC_I_OK:
               err=CheckIWatchpointError(hDlg);
               switch (err) {
                  case GOOD:
                     break;
                  case ERR_IW_INUSE_L:
                     MessageBox(hWndWatchPoint,
                        "I-Watchpoints are used by L-Watchpoints", "MP/SLD", MB_OK);
                     return TRUE;
                  case ERR_IW_INUSE_C:
                     MessageBox(hWndWatchPoint,
                        "I-Watchpoints are used by Counters", "MP/SLD", MB_OK);
                     return TRUE;

                  default:
                     MessageBox(hWndWatchPoint, "Invalid setting", "MP/SLD", MB_OK);
                     return TRUE;
               }
               for (i=0;i<4;i++) {
                  gIWhptAddr[i][0]='\0';
                  dwSel=SendDlgItemMessage(hDlg,IDC_I_A_CONDITION+i*10,
                     CB_GETCURSEL,0,0L);
                  if (dwSel!=cNotActive) {
                     gIWatchpoint.condition[i]=dwSel+cOffset; //for match FW
                     SendMessage(GetDlgItem(hDlg,IDC_I_A_ADDRESS+i*10),
                        WM_GETTEXT,sizeof(gIWhptAddr[i]),(DWORD)(LPSTR)gIWhptAddr[i]);
                     err=CheckAddressDataError(gIWhptAddr[i],&(gIWatchpoint.addr[i]),1);
                  }
                  else
                     gIWatchpoint.condition[i]=0;//disable

                  dwValue=SendDlgItemMessage(hDlg,IDC_I_IW0_BREAK+i*10,
                     BM_GETCHECK,0,0);
                  gIWatchpoint.enable[i]=dwValue;

                  dwSel=SendDlgItemMessage(hDlg,IDC_I_IW0_RELATION+i*10,
                     CB_GETCURSEL,0,0L);
                  if (dwSel!=relNotActive) {
                     gIWatchpoint.relation[i]=dwSel+relOffset;
                  }
                  else {
                     gIWatchpoint.relation[i] = 0; //disable
                     gIWatchpoint.enable[i] = 0;
                  }
               }
               EndDialog(hDlg,TRUE);
               return TRUE;
            case IDCANCEL:
            case IDC_I_CANCEL:
               EndDialog(hDlg,TRUE);
               return TRUE;

            case IDC_HELP:
               WinHelp(hDlg, "PWRVIEWS.HLP", HELP_CONTEXT, HE_IWATCHPOINT);
               return TRUE;
         }
         break;
   }
   return FALSE;
}

/***************************************************************
**
**            LWatchPointProc
**
****************************************************************/
BOOL FAR PASCAL LWatchPointProc (HWND hDlg, UINT message,
                UINT wParam, LONG lParam) {
int i, j;
U32 ulAddr;
DWORD dwValue,dwSel;
RETCODE err=1;
char tempString[20];

   switch(message) {
      case WM_INITDIALOG:
         SetupILCombox(hDlg,1);
         SetupLData(hDlg);
         return TRUE;
      case WM_COMMAND:
         switch(wParam) {
            case IDC_L_E_ADDRESS:
            case IDC_L_F_ADDRESS:
               if (HIWORD(lParam)==EN_KILLFOCUS) {
                  tempString[0]='\0';
                  SendMessage(GetDlgItem(hDlg,wParam),WM_GETTEXT,
                     sizeof(tempString),(LPARAM)(LPSTR)tempString);
                  if (tempString[0]!='\0') {
                     if ((err=ConvTextToU32(tempString,&ulAddr,1))!=GOOD) {
                        ErrDisplayError(err,FORCE_POPUP);
                        SetFocus(GetDlgItem(hDlg,wParam));
                        SendMessage(GetDlgItem(hDlg,wParam), EM_SETSEL, 0, 0xFFFF0000);
                        return TRUE;
                      }
                      wsprintf(tempString,"0x%lX",ulAddr);
                      SendMessage(GetDlgItem(hDlg,wParam),WM_SETTEXT,
                          sizeof(tempString),(LPARAM)(LPSTR)tempString);
                   }
               }
               return TRUE;
            case IDC_L_G_DATA:
            case IDC_L_H_DATA:
               if (HIWORD(lParam)==EN_KILLFOCUS) {
                  tempString[0]='\0';
                  SendMessage(GetDlgItem(hDlg,wParam),WM_GETTEXT,
                     sizeof(tempString),(LPARAM)(LPSTR)tempString);
                  if (tempString[0]!='\0') {
                     if ((err=ConvTextToU32(tempString,&ulAddr,0))!=GOOD) {
                        ErrDisplayError(err,FORCE_POPUP);
                        SetFocus(GetDlgItem(hDlg,wParam));
                        SendMessage(GetDlgItem(hDlg,wParam), EM_SETSEL, 0, 0xFFFF0000);
                        return TRUE;
                      }
                      wsprintf(tempString,"0x%lX",ulAddr);
                      SendMessage(GetDlgItem(hDlg,wParam),WM_SETTEXT,
                          sizeof(tempString),(LPARAM)(LPSTR)tempString);
                  }
               }
               return TRUE;

            case IDC_L_OK:
               err=CheckLWatchpointError(hDlg);
               switch (err) {
                  case GOOD:
                     break;
                  case ERR_L_ADDR_SETTING:
                     MessageBox(hWndWatchPoint,"Invalid setting of L-Address","MP/SLD",MB_OK);
                     return TRUE;
                  case ERR_L_DATA_SETTING:
                     MessageBox(hWndWatchPoint,"Invalid setting of L-Data","MP/SLD",MB_OK);
                     return TRUE;
                  case ERR_L_WATCHPOINT_SETTING:
                     MessageBox(hWndWatchPoint,"Invalid setting of L-Watchpoint","MP/SLD",MB_OK);
                     return TRUE;
                  case ERR_LW_INUSE:
                     MessageBox(hWndWatchPoint,"L-Watchpoints are used by Counters","MP/SLD",MB_OK);
                     return TRUE;
                  default:
                     MessageBox(hWndWatchPoint,"Assertion error!","MP/SLD",MB_OK);
                     return TRUE;
               }
               //L-Addr E, F
               for(i=0;i<2;i++) {
                  dwValue=SendDlgItemMessage(hDlg,IDC_L_E_ENABLE+i*10, //!! unused
                     BM_GETCHECK,0,0);                                 //!! unused
                  gLAddr.enable[i]=dwValue;                            //!! unused

                  gLWhptAddr[i][0]='\0';
                  dwSel=SendDlgItemMessage(hDlg,IDC_L_E_CONDITION+i*10,
                        CB_GETCURSEL,0,0L);
                  if (dwSel!=cNotActive) {
                     gLAddr.condition[i]=dwSel+cOffset;
                     SendMessage(GetDlgItem(hDlg,IDC_L_E_ADDRESS+i*10),
                        WM_GETTEXT,sizeof(tempString),(LPARAM)(LPSTR)gLWhptAddr[i]);
                     err=CheckAddressDataError(gLWhptAddr[i],&gLAddr.addr[i],1);
                     dwSel=SendDlgItemMessage(hDlg,IDC_L_E_RW+i*10,
                        CB_GETCURSEL,0,0L);
                     gLAddr.rw[i] = (dwSel+1) + rwOffset; //for meet FW
                  }
                  else 
                     gLAddr.condition[i]=0;  //no select
               }

               //L-Data G, H
               for(i=0;i<2;i++) {
                  dwValue=SendDlgItemMessage(hDlg,IDC_L_G_ENABLE+i*10, //!! unused
                     BM_GETCHECK,0,0);                                 //!! unused
                  gLData.enable[i]=dwValue;                            //!! unused

                  gLWhptData[i][0]='\0';
                  gLWhptMask[i][0]='\0';
                  dwSel=SendDlgItemMessage(hDlg,IDC_L_G_CONDITION+i*10,
                     CB_GETCURSEL,0,0L);
                  if (dwSel!=cNotActive) {
                     gLData.condition[i]=dwSel+cOffset;
                     dwValue=SendDlgItemMessage(hDlg,IDC_L_G_SIGNED+i*10,
                        BM_GETCHECK,0,0);
                     gLData.sign[i]=dwValue;
                     SendMessage(GetDlgItem(hDlg,IDC_L_G_DATA+i*10),
                        WM_GETTEXT,sizeof(gLWhptData[i]),(DWORD)(LPSTR)(gLWhptData[i]));
                     err=CheckAddressDataError(gLWhptData[i],&gLData.data[i],0);

                     gLData.mask[i]=SendDlgItemMessage(hDlg,IDC_L_G_MASK+i*10,
                        CB_GETCURSEL,0,0L);

                     dwSel=SendDlgItemMessage(hDlg,IDC_L_G_SIZE+i*10,
                        CB_GETCURSEL,0,0L);
                     gLData.size[i]=dwSel+sizeOffset; //for meet FW
                  }
                  else
                     gLData.condition[i]=0;//no select
               }

               // LW0, LW1
               for (i=0;i<2;i++) {
                  for (j=0; j<4; j++) { // clear in-use flags of IW0-IW3
                     bWhptInUse[i*4+j] = FALSE;
                  }
                  dwValue=SendDlgItemMessage(hDlg,IDC_L_LW0_ENABLE+i*10,
                     BM_GETCHECK,0,0);
                  gLWatchpoint.enable[i]=dwValue;

                  dwSel=SendDlgItemMessage(hDlg,IDC_L_LW0_IW+i*10,
                     CB_GETCURSEL,0,0L);
                  if (dwSel!=lwNotActive) {
                     gLWatchpoint.iw[i]=dwSel-lwOffset;
                     bWhptInUse[i*4+dwSel-lwOffset] = TRUE;
                  }
                  else
                     gLWatchpoint.iw[i]=NONACTIVE; //no select

                  dwSel=SendDlgItemMessage(hDlg,IDC_L_LW0_LADDR+i*10,
                     CB_GETCURSEL,0,0L);
                  if (dwSel!=lwNotActive)
                     gLWatchpoint.laddr[i]=dwSel-lwOffset;
                  else
                     gLWatchpoint.laddr[i]=NONACTIVE; //no select

                  dwSel=SendDlgItemMessage(hDlg,IDC_L_LW0_LDATA+i*10,
                     CB_GETCURSEL,0,0L);
                  if (dwSel!=lwNotActive)
                     gLWatchpoint.ldata[i]=dwSel-lwOffset;
                  else
                     gLWatchpoint.ldata[i]=NONACTIVE;//no select

                  if (gLWatchpoint.iw[i]    == NONACTIVE &&
                      gLWatchpoint.laddr[i] == NONACTIVE &&
                      gLWatchpoint.ldata[i] == NONACTIVE) {
                     gLWatchpoint.enable[i] = FALSE;
                  }
               }
               EndDialog(hDlg,TRUE);
               return TRUE;
            case IDCANCEL:
            case IDC_L_CANCEL:
               EndDialog(hDlg,TRUE);
               return TRUE;

            case IDC_HELP:
               WinHelp(hDlg, "PWRVIEWS.HLP", HELP_CONTEXT, HE_LWATCHPOINT);
               return TRUE;
         }
         break;
   }
   return FALSE;
}

/***************************************************************
**
**            CounterProc
**
****************************************************************/
BOOL FAR PASCAL CounterProc (HWND hDlg, UINT message,
                UINT wParam, LONG lParam) {
DWORD dwValue;
char tempString[20];
int i;
U32 ulAddr;
RETCODE err;

   switch(message) {
      case WM_INITDIALOG:
         for (i=0;i<2;i++) {
            SendDlgItemMessage(hDlg,IDC_C_A_ENABLE+i*10,BM_SETCHECK,
               gWatchCounter.enable[i],0L);
            EnableWindow(GetDlgItem(hDlg,IDC_C_A_ENABLE+i*10+1),gWatchCounter.enable[i]);
            EnableWindow(GetDlgItem(hDlg,IDC_C_A_ENABLE+i*10+2),gWatchCounter.enable[i]);
            EnableWindow(GetDlgItem(hDlg,IDC_C_A_ENABLE+i*10+3),gWatchCounter.enable[i]);

            if (gWatchCounter.count[i]==0)
               tempString[0]='\0';
            else
               ultoa(gWatchCounter.count[i],tempString,10);
            SetWindowText(GetDlgItem(hDlg,IDC_C_A_COUNT+i*10),tempString);
            SendDlgItemMessage(hDlg,IDC_C_A_IW0+gWatchCounter.ilw[i]-1+i*10,
               BM_SETCHECK,1,0l);
         }
         return TRUE;

      case WM_COMMAND:
         switch(wParam) {
            case IDC_C_A_ENABLE:
            case IDC_C_B_ENABLE:
               if (HIWORD(lParam)==BN_CLICKED) {
                  dwValue=SendDlgItemMessage(hDlg,wParam,BM_GETCHECK,0,0);
                  //IDC_C_?_COUNT,IW?,LW?
                  EnableWindow(GetDlgItem(hDlg,wParam+1),dwValue);
                  EnableWindow(GetDlgItem(hDlg,wParam+2),dwValue);
                  EnableWindow(GetDlgItem(hDlg,wParam+3),dwValue);
               }
               return TRUE;
            case IDC_C_A_COUNT:
            case IDC_C_B_COUNT:
               if (HIWORD(lParam)==EN_KILLFOCUS) {
                  tempString[0]='\0';
                  SendMessage(GetDlgItem(hDlg,wParam),WM_GETTEXT,
                     sizeof(tempString),(LPARAM)(LPSTR)tempString);
                  if (tempString[0]!='\0') {
                     if ((err=ConvTextToU32(tempString,&ulAddr,0))!=GOOD) {
                        ErrDisplayError(err,FORCE_POPUP);
                        SetFocus(GetDlgItem(hDlg,wParam));
                        SendMessage(GetDlgItem(hDlg,wParam), EM_SETSEL, 0, 0xFFFF0000);
                        return TRUE;
                      }
                      if (ulAddr > 65535) ulAddr = 65535;
                      wsprintf(tempString,"%u",ulAddr);
                      SendMessage(GetDlgItem(hDlg,wParam),WM_SETTEXT,
                          sizeof(tempString),(LPARAM)(LPSTR)tempString);
                  }
               }
               return TRUE;
            case IDC_C_A_IW0:
            case IDC_C_A_LW0:
               dwValue=SendDlgItemMessage(hDlg,IDC_C_A_IW0,
                  BM_SETCHECK,0,0);
               dwValue=SendDlgItemMessage(hDlg,IDC_C_A_LW0,
                  BM_SETCHECK,0,0);
               dwValue=SendDlgItemMessage(hDlg,wParam,
                  BM_SETCHECK,TRUE,0);
               return TRUE;
            case IDC_C_B_IW1:
            case IDC_C_B_LW1:
               dwValue=SendDlgItemMessage(hDlg,IDC_C_B_IW1,
                  BM_SETCHECK,0,0);
               dwValue=SendDlgItemMessage(hDlg,IDC_C_B_LW1,
                  BM_SETCHECK,0,0);
               dwValue=SendDlgItemMessage(hDlg,wParam,
                  BM_SETCHECK,TRUE,0);
               return TRUE;
            case IDC_C_OK:
               switch (CheckCounterError(hDlg)) {
                  case GOOD:
                     break;
                  case ERR_C_IW_MISS:
                     MessageBox(hWndWatchPoint,"IW0 or IW1 is not available.","MP/SLD",MB_OK);
                     return TRUE;
                  case ERR_C_LW_MISS:
                     MessageBox(hWndWatchPoint,"LW0 or LW1 is not available.","MP/SLD",MB_OK);
                     return TRUE;
                  default:
                     MessageBox(hWndWatchPoint,"Invalid counter value","MP/SLD",MB_OK);
                     return TRUE;
               }
               for (i=0;i<2;i++) {
                  dwValue=SendDlgItemMessage(hDlg,IDC_C_A_ENABLE+i*10,
                     BM_GETCHECK,0,0);
                  gWatchCounter.enable[i]=dwValue;
                  if (!dwValue) { // not active
                     bWhptInUse[C_IW0+i] = FALSE;
                     bWhptInUse[C_LW0+i] = FALSE;
                  }
                  gCCount[i][0]='\0';
                  SendMessage(GetDlgItem(hDlg,IDC_C_A_COUNT+i*10),
                     WM_GETTEXT,sizeof(gCCount[i]),(DWORD)(LPSTR)gCCount[i]);
                  err=CheckAddressDataError(gCCount[i],&gWatchCounter.count[i],0);
                  dwValue=SendDlgItemMessage(hDlg,IDC_C_A_IW0+i*10,
                     BM_GETCHECK,0,0);
                  if (dwValue) {
                     gWatchCounter.ilw[i]=IW;
                     bWhptInUse[C_IW0+i] = TRUE;
                     bWhptInUse[C_LW0+i] = FALSE;
                  }
                  else {
                     gWatchCounter.ilw[i]=LW;
                     bWhptInUse[C_LW0+i] = TRUE;
                     bWhptInUse[C_IW0+i] = FALSE;
                  }
               }
               EndDialog(hDlg,TRUE);
               return TRUE;
            case IDCANCEL:
            case IDC_C_CANCEL:
               EndDialog(hDlg,TRUE);
               return TRUE;

            case IDC_HELP:
               WinHelp(hDlg, "PWRVIEWS.HLP", HELP_CONTEXT, HE_COUNTER);
               return TRUE;
         }
         break;
   }
   return FALSE;
}

/***************************************************************
**
**            CheckLWatchpointError
**
****************************************************************/
RETCODE CheckLWatchpointError(HWND hDlg) {
DWORD dwSel,dwValue,err=999;
char tempString[20];
int i;
BOOL bActive;

   for (i=0;i<2;i++) {
      dwSel=SendDlgItemMessage(hDlg,IDC_L_E_CONDITION+i*10,CB_GETCURSEL,0,0L);
      tempString[0]='\0';
      SendMessage(GetDlgItem(hDlg,IDC_L_E_ADDRESS+i*10),WM_GETTEXT,
         sizeof(tempString),(LPARAM)(LPSTR)tempString);
      if (dwSel!=0 && tempString[0]=='\0')
          return ERR_L_ADDR_SETTING;
   }
   for (i=0;i<2;i++) {
      dwSel=SendDlgItemMessage(hDlg,IDC_L_G_CONDITION+i*10,CB_GETCURSEL,0,0L);
      tempString[0]='\0';
      SendMessage(GetDlgItem(hDlg,IDC_L_G_DATA+i*10),WM_GETTEXT,
           sizeof(tempString),(LPARAM)(LPSTR)tempString);
      if (dwSel!=0 && tempString[0]=='\0')
          return ERR_L_DATA_SETTING;
   }

   for (i=0;i<2;i++) {
      bActive = FALSE; // assume LW doesn't have setting

      dwSel=SendDlgItemMessage(hDlg,IDC_L_LW0_IW+i*10,CB_GETCURSEL,0,0L);
      if (dwSel!=lwNotActive) {
         if (gIWatchpoint.relation[dwSel-lwOffset] == 0)
            return ERR_L_WATCHPOINT_SETTING;
         bActive = TRUE; // it has I-Watchpoint
      }
      dwSel=SendDlgItemMessage(hDlg,IDC_L_LW0_LADDR+i*10,CB_GETCURSEL,0,0L);
      if (dwSel!=lwNotActive) {
         switch(dwSel) {
            case 1:
            case 2:
               dwSel=SendDlgItemMessage(hDlg,IDC_L_E_CONDITION+(dwSel-lwOffset)*10,
                  CB_GETCURSEL,0,0L);
               if (dwSel==0)
                  return err;
               break;
            case 3:
            case 4:
               dwSel=SendDlgItemMessage(hDlg,IDC_L_E_CONDITION,CB_GETCURSEL,0,0L);
               dwValue=SendDlgItemMessage(hDlg,IDC_L_F_CONDITION,CB_GETCURSEL,0,0L);
               if (dwSel==0 || dwValue==0)
                  return err;
               break;
         }
         bActive = TRUE; // has L-Address
      }
      dwSel=SendDlgItemMessage(hDlg,IDC_L_LW0_LDATA+i*10,CB_GETCURSEL,0,0L);
      if (dwSel!=0) {
         switch(dwSel) {
             case 1:
             case 2:
                dwSel=SendDlgItemMessage(hDlg,IDC_L_G_CONDITION+(dwSel-lwOffset)*10,
                   CB_GETCURSEL,0,0L);
                if (dwSel==0)
                   return err;
                break;
             case 3:
             case 4:
                dwSel=SendDlgItemMessage(hDlg,IDC_L_G_CONDITION,CB_GETCURSEL,0,0L);
                dwValue=SendDlgItemMessage(hDlg,IDC_L_H_CONDITION,CB_GETCURSEL,0,0L);
                if (dwSel==0 || dwValue==0)
                   return err;
                break;
         }
         bActive = TRUE; // has L-Data
      }

      if (!bActive) { // LW has no setting
         if (gWatchCounter.enable[i] && bWhptInUse[C_LW0+i])
            return ERR_LW_INUSE;
      }
   }
   return GOOD;
}

/***************************************************************
**
**            CheckIWatchpointError
**
****************************************************************/
RETCODE CheckIWatchpointError(HWND hDlg) {
DWORD dwSel,dwValue,err=999;
char tempString[20];
U32  tempID;
int i;
   for (i=0;i<4;i++) {
      dwSel=SendDlgItemMessage(hDlg,IDC_I_A_CONDITION+i*10,CB_GETCURSEL,0,0L);
      tempString[0]='\0';
      SendMessage(GetDlgItem(hDlg,IDC_I_A_ADDRESS+i*10),WM_GETTEXT,sizeof(tempString),
         (LPARAM)(LPSTR)tempString);
      if (dwSel!=0 && tempString[0]=='\0')
         return err;
   }

   for (i=0; i<4; i++) {
      dwSel = SendDlgItemMessage(hDlg,IDC_I_IW0_RELATION+i*10,CB_GETCURSEL,0,0L);
      switch(dwSel) {
         case relNotActive:
            if (bWhptInUse[L0_IW0+i] || bWhptInUse[L1_IW0+i])
               return ERR_IW_INUSE_L;
            if (i<2 && gWatchCounter.enable[i] && bWhptInUse[C_IW0+i])
               return ERR_IW_INUSE_C;
            break;
         case 1:
            dwSel=SendDlgItemMessage(hDlg,IDC_I_A_CONDITION+i*10,
                                     CB_GETCURSEL,0,0L);
            if (dwSel == cNotActive) return err;
            break;
         case 2:
            tempID=i/2*2;
            dwSel=SendDlgItemMessage(hDlg,IDC_I_A_CONDITION+tempID*10,CB_GETCURSEL,0,0L);
            dwValue=SendDlgItemMessage(hDlg,IDC_I_A_CONDITION+10*(tempID+1),CB_GETCURSEL,0,0L);
            if (dwSel==cNotActive || dwValue==cNotActive)
               return err;
            break;
         default:
            return err;
      }
   }

   return GOOD;
}

/***************************************************************
**
**            CheckCounterError
**
****************************************************************/
RETCODE CheckCounterError(HWND hDlg) {
RETCODE err=999;
char tempString[20];
DWORD dwSel;
int i;

   for (i=0;i<2;i++) {
      dwSel=SendDlgItemMessage(hDlg,IDC_C_A_ENABLE+i*10,BM_GETCHECK,0,0L);
      if (dwSel==1) {
         tempString[0]='\0';
         SendMessage(GetDlgItem(hDlg,IDC_C_A_COUNT+i*10),WM_GETTEXT,sizeof(tempString),
            (LPARAM)(LPSTR)tempString);
         if (tempString[0]=='\0')
             return err;

         if (SendDlgItemMessage(hDlg,IDC_C_A_IW0+i*10,BM_GETCHECK,0,0)) { //IW is selected
            if (gIWatchpoint.relation[i] == 0)
               return ERR_C_IW_MISS;
         }
         else {
            if (gLWatchpoint.iw[i]    == NONACTIVE &&
                gLWatchpoint.laddr[i] == NONACTIVE &&
                gLWatchpoint.ldata[i] == NONACTIVE) {
               return ERR_C_LW_MISS;
            }
         }
      }
   }
   return GOOD;

}
/***************************************************************
**
**            CombineDataMask
**
****************************************************************/
RETCODE CombineDataMask(char *string,U32 mask) {
U8 byteMask[4]={0,0,0,0};
char *ptr;
U8 len,i,j;
U32 tempMask;

   tempMask=mask;
   for (i=0;i<4;i++) {
      if ((tempMask & 0x1)==1)
         byteMask[i]=1;
      tempMask=tempMask>>1;
   }
   len=strlen(string);
   ptr=&string[len-1];
   i=0;
   j=0;
   while (*ptr!='x') {
      if (byteMask[i]==1)
         *ptr='*';
      ptr--;
      j++;
      if (j==2) {
        i++;
        j=0;
      }
   }

   return(GOOD);
}
/***************************************************************
**
**            CheckDataError
**
****************************************************************/
#pragma argsused
RETCODE CheckDataError(U32 data) {

   return GOOD;
}
/***************************************************************
**
**            CheckAddressDataError
**   flag=1: addr , 0:data
****************************************************************/
RETCODE CheckAddressDataError(char *string,U32 *value,U8 flag) {
char tempString[20];
RETCODE err;

    strcpy(tempString,string);
    err=ConvTextToU32(tempString,value,flag);
    if (err!=GOOD)
       return err;
    if (flag==0)
       wsprintf(string,"0x%lX",*value);
    return GOOD;
}
/***************************************************************
**
**           ConvertMask
**
****************************************************************/
/******!!!!!!!
RETCODE ConvertMask(U32 *mask,char *string) {
U8  i;
U32 tempMask,sMask;

    if (string[0]=='\0')
       return GOOD;
    ConvTextToU32(string,&tempMask,0);

    *mask=0;
    sMask=1;
    for (i=0;i<4;i++) {
       if ((tempMask & 0xff)==0x0)
          *mask=(sMask | *mask);
       else
          if ((tempMask & 0xff)!=0xff)
             return 1;
       sMask=sMask<<1;
       tempMask=tempMask>>8;
    }
    return GOOD;
}
!!!!!!!!! ***/
/***************************************************************
**
**           ConvertOrigMask
**
****************************************************************/
RETCODE ConvertOrigMask(U32 mask,U32 *tMask) {
U8  i;
U32 tempMask,sMask;

    *tMask=0;
    tempMask=mask;
    sMask=0xFF;
    for (i=0;i<4;i++) {
       if ((tempMask & 0x1)==0x0)
          *tMask=(sMask | *tMask);
       sMask=sMask<<8;
       tempMask=tempMask>>1;
    }
    return GOOD;
}

/***************************************************************
**
**           SetupILCombox
**
****************************************************************/
RETCODE SetupILCombox(HWND hDlg,U8 flag) {  //flag=0:i-whpt, 1:l-whpt
char szString[5][15]={"Not active","Equal to","Less than","Greater than","Not equal to"};
char szString00[12][12]={"Not active","A","A & B",
                         "Not active","B","A | B",
                         "Not active","C","C & D",
                         "Not active","D","C | D"};
char szString01[3][12]= {"Don't care","Read only","Write only"};
char szString02[3][12]= {"Word","Half Word","Byte"};
char szString03[15][12]={"Not active","IW0","IW1","IW2","IW3",
                         "Not active","E","F","E & F","E | F",
                         "Not active","G","H","G & H","G | H"};
char szStringMask[16][10]= {"00000000","000000FF","0000FF00","0000FFFF",
                            "00FF0000","00FF00FF","00FFFF00","00FFFFFF",
                            "FF000000","FF0000FF","FF00FF00","FF00FFFF",
                            "FFFF0000","FFFF00FF","FFFFFF00","FFFFFFFF",
};

int i,j,k;
U8 condition;

    condition=flag ? IDC_L_E_CONDITION : IDC_I_A_CONDITION;
    for (i=0;i<4;i++)
      for (j=0;j<5;j++)
         SendDlgItemMessage(hDlg,condition+i*10,CB_ADDSTRING,0,
            (LPARAM)(LPSTR)szString[j]);

    if (flag==0) {
       for (i=0;i<4;i++)
          for (j=0;j<3;j++)
             SendDlgItemMessage(hDlg,IDC_I_IW0_RELATION+i*10,CB_ADDSTRING,0,
               (LPARAM)(LPSTR)szString00[i*3+j]);
    }
    else {
       for (i=0;i<2;i++)
          for (j=0;j<3;j++)
             SendDlgItemMessage(hDlg,IDC_L_E_RW+i*10,CB_ADDSTRING,0,
                (LPARAM)(LPSTR)szString01[j]);
       for (i=0;i<2;i++)
          for (j=0;j<16;j++)
             SendDlgItemMessage(hDlg,IDC_L_G_MASK+i*10,CB_ADDSTRING,0,
                (LPARAM)(LPSTR)szStringMask[j]);
       for (i=0;i<2;i++)
          for (j=0;j<3;j++)
             SendDlgItemMessage(hDlg,IDC_L_G_SIZE+i*10,CB_ADDSTRING,0,
                (LPARAM)(LPSTR)szString02[j]);
       for (i=0;i<2;i++)
          for (k=0;k<3;k++)
             for (j=0;j<5;j++)
                SendDlgItemMessage(hDlg,IDC_L_LW0_IW+i*10+k,CB_ADDSTRING,0,
                   (LPARAM)(LPSTR)szString03[5*k+j]);
    }
   return(GOOD);
}
/***************************************************************
**
**           SetupIData
**
****************************************************************/
RETCODE SetupIData(HWND hDlg) {
int i;

   for (i=0;i<4;i++) {
      if (gIWatchpoint.condition[i]==0)
         SendDlgItemMessage(hDlg,IDC_I_A_CONDITION+i*10,CB_SETCURSEL,
            cNotActive,0L);
      else
         SendDlgItemMessage(hDlg,IDC_I_A_CONDITION+i*10,CB_SETCURSEL,
            gIWatchpoint.condition[i]-cOffset,0L);
      SetWindowText(GetDlgItem(hDlg,IDC_I_A_ADDRESS+i*10),gIWhptAddr[i]);
      SendDlgItemMessage(hDlg,IDC_I_IW0_BREAK+i*10,BM_SETCHECK,
         gIWatchpoint.enable[i],0L);
      if (gIWatchpoint.relation[i]==0)
         SendDlgItemMessage(hDlg,IDC_I_IW0_RELATION+i*10,CB_SETCURSEL,
            relNotActive,0L);
      else
         SendDlgItemMessage(hDlg,IDC_I_IW0_RELATION+i*10,CB_SETCURSEL,
            gIWatchpoint.relation[i]-relOffset,0L);
   }
   return(GOOD);
}

/***************************************************************
**
**           SetupLData
**
****************************************************************/
RETCODE SetupLData(HWND hDlg) {
int i;
char tempString[20];

   for (i=0;i<2;i++) {
      if (gLAddr.condition[i]==0)
         SendDlgItemMessage(hDlg,IDC_L_E_CONDITION+i*10,CB_SETCURSEL,
            cNotActive,0l);
      else
         SendDlgItemMessage(hDlg,IDC_L_E_CONDITION+i*10,CB_SETCURSEL,
            gLAddr.condition[i]-cOffset,0l);
      SetWindowText(GetDlgItem(hDlg,IDC_L_E_ADDRESS+i*10),gLWhptAddr[i]);
      if (gLAddr.rw[i]==0)
         SendDlgItemMessage(hDlg,IDC_L_E_RW+i*10,CB_SETCURSEL,
            rwNotActive,0l);
      else
         SendDlgItemMessage(hDlg,IDC_L_E_RW+i*10,CB_SETCURSEL,
            gLAddr.rw[i]-rwOffset-1, 0l);
   }
   for (i=0;i<2;i++) {
      if (gLData.condition[i]==0)
         SendDlgItemMessage(hDlg,IDC_L_G_CONDITION+i*10,CB_SETCURSEL,
            cNotActive,0l);
      else
         SendDlgItemMessage(hDlg,IDC_L_G_CONDITION+i*10,CB_SETCURSEL,
            gLData.condition[i]-cOffset,0l);
      SendDlgItemMessage(hDlg,IDC_L_G_SIGNED+i*10,BM_SETCHECK,
         gLData.sign[i],0L);
      if (gLData.condition[i]!=0)
         wsprintf(tempString,"0x%lX",gLData.data[i]);
      else
         tempString[0]='\0';
      SetWindowText(GetDlgItem(hDlg,IDC_L_G_DATA+i*10),tempString);

      SendDlgItemMessage(hDlg,IDC_L_G_MASK+i*10,CB_SETCURSEL,
         gLData.mask[i],0l);

      if (gLData.size[i]==0)
         SendDlgItemMessage(hDlg,IDC_L_G_SIZE+i*10,CB_SETCURSEL,
            sizeNotActive,0l);
      else
         SendDlgItemMessage(hDlg,IDC_L_G_SIZE+i*10,CB_SETCURSEL,
            gLData.size[i]-sizeOffset,0l);
   }
   for (i=0;i<2;i++) {
      SendDlgItemMessage(hDlg,IDC_L_LW0_ENABLE+i*10,BM_SETCHECK,
         gLWatchpoint.enable[i],0L);

      if (gLWatchpoint.iw[i]==NONACTIVE)
         SendDlgItemMessage(hDlg,IDC_L_LW0_IW+i*10,CB_SETCURSEL,
            lwNotActive,0l);
      else
         SendDlgItemMessage(hDlg,IDC_L_LW0_IW+i*10,CB_SETCURSEL,
            gLWatchpoint.iw[i]+lwOffset,0l);
      if (gLWatchpoint.laddr[i]==NONACTIVE)
         SendDlgItemMessage(hDlg,IDC_L_LW0_LADDR+i*10,CB_SETCURSEL,
            lwNotActive,0l);
      else
         SendDlgItemMessage(hDlg,IDC_L_LW0_LADDR+i*10,CB_SETCURSEL,
            gLWatchpoint.laddr[i]+lwOffset,0l);
      if (gLWatchpoint.ldata[i]==NONACTIVE)
         SendDlgItemMessage(hDlg,IDC_L_LW0_LDATA+i*10,CB_SETCURSEL,
            lwNotActive,0l);
      else
         SendDlgItemMessage(hDlg,IDC_L_LW0_LDATA+i*10,CB_SETCURSEL,
            gLWatchpoint.ldata[i]+lwOffset,0l);
   }

   return(GOOD);
}

/********
RETCODE EXPORT WhptSetIW(U8 iw, U32 addr, U8 enable) {
   gIWatchpoint.condition[iw] = enable? 4: 0;  //equal to
   gIWatchpoint.addr[iw] = addr;
   gIWatchpoint.enable[iw] = enable;
   gIWatchpoint.relation[iw] = enable? 2: 0;   // iw2 is C, iw3 is D

   return GOOD;
}

RETCODE EXPORT WhptHwBkptEnable(U8* enable) {
   *enable = bHwBkpt;

   return GOOD;
}
***********/
/*---------------------------------------------------------------------------
**  SendCliMessage
**
**  Description:
**     Send a text string to CLI
**
**  Input parameters:
**        msgPtr:     message pointer
----------------------------------------------------------------------------*/
RETCODE PRIVATE SendCliMessage(LPSTR msgPtr) {

   HANDLE msgBufHandle;
   CSERVER_RESULTS FAR  *msgBufPtr;
   U16         msgTextSize, loop ;

   if (!cliServerHandle)  /* don't do anything if not a valid cli handle */
      return GOOD;
   msgTextSize = lstrlen(msgPtr);
   msgBufHandle = GlobalAlloc(GMEM_MOVEABLE,
                              (sizeof(CSERVER_RESULTS) + msgTextSize + 2));
   if (msgBufHandle == (HANDLE)NULL) {
      return(ER_OUT_OF_MEMORY); /* FAILED */
   }
   else if((msgBufPtr=(CSERVER_RESULTS *)GlobalLock(msgBufHandle)) == NULL) {
      return(ER_WINDOWS_MEMLOCK) ; /* FAILED */
   }
   msgBufPtr->target               = 0;        /* CLI: not yet def'ed */
   msgBufPtr->variantCode          = CLI_SERVER_RESULTS;
   msgBufPtr->resultTextLength     = msgTextSize; /* message string length */
   for (loop = 0; loop < msgTextSize; loop++ ) {
      msgBufPtr->messageText[loop]  =  *msgPtr++;
   }
   msgBufPtr->messageText[msgTextSize+1] = 0 ;

   /* output message to memBufPtr->messageText[] */
   GlobalUnlock(msgBufHandle);

   SendMessage(cliServerHandle, CLI_SERVER_RESULTS,
               msgBufHandle, CLI_SERVER_RESULTS);
   return GOOD;
}

/*---------------------------------------------------------------------------
**  WhptCliSetISCT_SER
**
** Syntax: "ISCT_SER <value>"
**
----------------------------------------------------------------------------*/
RETCODE EXPORT WhptCliSetISCT_SER(LPSTR cmdString, U32 argc, U32 argv[]) {
U32 val;
char *endptr;

   if (argc != 2)
      return ER_CLI_SYNTAX;

   val = strtoul(&cmdString[(U16)argv[1]], &endptr, 0);
   if (*endptr!='\0')
      return ER_CLI_SYNTAX;

   Sds2AbiFwSetISCT_SER((U16)val);

   return (GOOD);
}

/*---------------------------------------------------------------------------
**  WhptCliSetBkptNonmask
**
** Syntax: "bkptNonmask [enable|disable]"
**
----------------------------------------------------------------------------*/
RETCODE EXPORT WhptCliSetBkptNonmask(LPSTR cmdString, U32 argc, U32 argv[]) {

   switch (argc) {
      case 1:
         SendCliMessage(nonMaskBit? "Enabled": "Disabled");
         break;
      case 2:
         if (strncmpi(&cmdString[(U16)argv[1]], "enable",
                          strlen(&cmdString[(U16)argv[1]]))==0) {
            nonMaskBit = TRUE;
         }
         else if (strncmpi(&cmdString[(U16)argv[1]], "disable",
                          strlen(&cmdString[(U16)argv[1]]))==0) {
            nonMaskBit = FALSE;
         }
         else
            return ER_CLI_SYNTAX;

         Sds2AbiFwSetBkptNonmask((U16)nonMaskBit);
         break;

      default:
         return ER_CLI_SYNTAX;
   }
   return(GOOD);
}

/**********************EOF********************************************/
