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

/////////////////////////////////////////////////////////////////////////////
//
//  File name:  TRCWIN.CPP
//
//  Description:The implement file for the class: CTraceWindow
//
//  Author:     Chris Fang
//
//  Date:       5/05/97
//
//  Modification:
//
//      1. 5/05/97, Initial version
//
//
//  Copyright (C) 1997 Microtek International. All rights reserved.
//
/////////////////////////////////////////////////////////////////////////////

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

#include "ep196.h"
#include "trcwin.h"
#include "uicom2.h"
#include "trcpub.h"
#include "trcgrpdi.h"
#include "trcfidlg.h"
#include "srcexp.h"
#include "flttool.h"
#include "trcgtdlg.h"
#include "trcschdg.h"                                                                           
                                                                           
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

#define MAX_LINENUM 50
#define CL_DISCARDLINENUM 1

int	nTraceViewOption;                   
static BOOL g_bCanSearchNext = FALSE;

extern CString g_trcSearchContent;     
extern int g_nTrcSearchMode;



void TrcOpenWindow(CMDIFrameWnd * pParent)
{
	if(gb_isTraceOn)
		return;

	if(nTraceViewOption==0)						//init
		nTraceViewOption = CTraceWindow::TRACEMODE_BUS;

	gp_TraceWnd = new CTraceWindow;
	if(!((CTraceWindow *)gp_TraceWnd)->Create(
		WS_CHILD|WS_VISIBLE|WS_OVERLAPPEDWINDOW,
		CFrameWnd::rectDefault, pParent))
		ASSERT(0);

	gb_isTraceOn = TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CTraceWindow

//////////////////////////////////////////////
CMenu NEAR CTraceWindow::m_menu;                              

IMPLEMENT_DYNCREATE(CTraceWindow, CMDIChildWnd)

CTraceWindow::CTraceWindow()
{
	m_nIDHelp = IDR_TRACE;
	
	m_nTitleHeight=20;
	m_bHscOn=FALSE;
	m_bVscOn=FALSE;
	m_nHscMaxpos=0;
	m_nLeftfrom=0;
	m_nPrevcx=0;
	m_nPrevcy=0;
	
	m_dwLastFrame=TS_GetLastFrame();
//	m_nScrUnit=int((m_dwLastFrame+1)/0x8000l+1);
	m_nScrUnit=int((m_dwLastFrame)/0x8000l+1);
	m_dwCurFrame=0;    
	m_byCurInt = 0;
	m_wLines=0;
	m_wFrameLines=0;
	
	//m_pBusBuffer=NULL;
	m_pBusBuffer=new FrameData[MAX_LINENUM];
	m_pInsBuffer=new InsData[MAX_LINENUM];

	m_bCurSorLink=FALSE;
	
}

CTraceWindow::~CTraceWindow()
{
	gb_isTraceOn = FALSE;
	if(m_pBusBuffer)
		delete m_pBusBuffer;              
	if(m_pInsBuffer)
		delete m_pInsBuffer;		
}

BOOL CTraceWindow::Create(LONG style,
    const RECT& rect, CMDIFrameWnd * pParent)
{
char	szTitle[20];

	// Setup the shared m_menu
	if(m_menu.m_hMenu == NULL)
		m_menu.LoadMenu(IDR_TRACE);
	m_hMenuShared = m_menu.m_hMenu;

	wsprintf(szTitle, "Trace[%04X]", m_dwLastFrame);

	const char * pszTraceClass =
		AfxRegisterWndClass(CS_HREDRAW,
            LoadCursor(NULL, IDC_ARROW),
//			NULL,           //for easily change mouse cursor when recolumn
			(HBRUSH)(COLOR_WINDOW + 1),
			AfxGetApp()->LoadIcon(IDR_TRACE));
	return CMDIChildWnd::Create(pszTraceClass, szTitle,
		style, rect, pParent);
}

/****************************************************************************
**
**  Name: CTraceWindow::SetColData
**
**  Description: Set class member data m_nColnum, m_cdData rely on 
**				 m_nTraceMode, m_nCharWidth and data length in this col.
**				 You should modify this function for different case.
**  Parameters:
**     input:   
**     output:
**
**  Return data:
**
****************************************************************************/
void CTraceWindow::SetColData(void)
{                                      
	switch(nTraceViewOption){
		case TRACEMODE_BUS:
			m_nColnum=5;
			m_cdData[0].strTitle="Frame ";
			m_cdData[0].nPosx=0;
			m_cdData[0].nWidth=m_cdData[0].strTitle.GetLength()*m_nCharWidth;
			m_cdData[1].strTitle=" Address  ";
			m_cdData[1].nPosx=m_cdData[0].nPosx+m_cdData[0].nWidth;
			m_cdData[1].nWidth=m_cdData[1].strTitle.GetLength()*m_nCharWidth;
			m_cdData[2].strTitle=" Data  ";
			m_cdData[2].nPosx=m_cdData[1].nPosx+m_cdData[1].nWidth;
			m_cdData[2].nWidth=m_cdData[2].strTitle.GetLength()*m_nCharWidth;
			m_cdData[3].strTitle="Status ";
			m_cdData[3].nPosx=m_cdData[2].nPosx+m_cdData[2].nWidth;
			m_cdData[3].nWidth=m_cdData[3].strTitle.GetLength()*m_nCharWidth;
			m_cdData[4].strTitle="Spare ";
			m_cdData[4].nPosx=m_cdData[3].nPosx+m_cdData[3].nWidth;
			m_cdData[4].nWidth=m_cdData[4].strTitle.GetLength()*m_nCharWidth;
			m_nLineWidth=m_cdData[4].nPosx+m_cdData[4].nWidth;
			//	m_cdData[5].strTitle="Port ";
			//	m_cdData[5].nPosx=m_cdData[4].nPosx+m_cdData[4].nWidth;
			//	m_cdData[5].nWidth=m_cdData[5].strTitle.GetLength()*m_nCharWidth;
			//	m_nLineWidth=m_cdData[5].nPosx+m_cdData[5].nWidth;
			break;
		case TRACEMODE_INSTRUCTION:
			m_nColnum=3;
			m_cdData[0].strTitle="Frame ";
			m_cdData[0].nPosx=0;
			m_cdData[0].nWidth=m_cdData[0].strTitle.GetLength()*m_nCharWidth;
			m_cdData[1].strTitle="  Address   ";
			m_cdData[1].nPosx=m_cdData[0].nPosx+m_cdData[0].nWidth;
			m_cdData[1].nWidth=m_cdData[1].strTitle.GetLength()*m_nCharWidth;
			m_cdData[2].strTitle="Instruction ";
			m_cdData[2].nPosx=m_cdData[1].nPosx+m_cdData[1].nWidth;
			m_cdData[2].nWidth=m_cdData[2].strTitle.GetLength()*m_nCharWidth;
			m_nLineWidth=m_cdData[2].nPosx+m_cdData[2].nWidth; // temporal used
			break;
		default: ASSERT(0);
	}
}

/****************************************************************************
**
**  Name: CTraceWindow::OnBufferChange
**
**  Description: call when lastframe change. Now should set m_dwLastFrame,
**				 calculate vscrollbar and set window title.
**  Parameters:
**     input:   
**     output:	 
**
**  Return data:
**
****************************************************************************/
void CTraceWindow::OnBufferChange(void)
{
char	title[20];
int		cy=m_nPrevcy;
    
    DWORD dwFrameNum = TS_GetLastFrame();
    
	if(m_dwLastFrame==dwFrameNum)
		return;
	m_dwLastFrame=dwFrameNum;
//	m_nScrUnit=int((m_dwLastFrame+1)/0x8000l+1);
	m_nScrUnit=int(m_dwLastFrame/0x8000l+1);
	m_dwCurFrame=min(m_dwCurFrame, m_dwLastFrame);
	wsprintf(title, "Trace[%04X]", m_dwLastFrame);
	SetWindowText(title);
	m_nPrevcy=0xffff;

	if(cy==0xffff)
	{
		RECT	rect;
		GetClientRect(&rect);
		cy=rect.bottom;
	}

	//because m_nPrevcy>cy, PrepareData will not be called in OnSize.
	SendMessage(WM_SIZE, SIZE_RESTORED, MAKELONG(m_nPrevcx, cy));
//	Invalidate();
}

/****************************************************************************
**
**  Name: CTraceWindow::PrepareData
**
**  Description: Get trace data from trace server rely on m_nTraceMode,
**				 m_dwCurFrame, m_wLines. At least must get one line.
**  Parameters:
**     input:   
**     output:	 will modify class member data m_wFrameLines, m_dwCurFrame.
**
**  Return data:
**
****************************************************************************/
void CTraceWindow::PrepareData(void)
{
int 	nRet;
DWORD	dwFrameLines=max(1, m_wLines);

	OnBufferChange();
	ASSERT(dwFrameLines<=MAX_LINENUM);
	if(m_dwLastFrame==0)
	{
		m_wFrameLines=0;
		return;
	}    
	
	BeginWaitCursor();
	                                        
	switch(nTraceViewOption){
		case TRACEMODE_BUS:
			nRet=TS_GetBusRecord(m_nReadDirect, m_dwCurFrame, dwFrameLines,
								m_pBusBuffer);                             
			break;
		case TRACEMODE_INSTRUCTION:
			nRet=TS_GetInsRecord(m_nReadDirect, m_dwCurFrame, m_byCurInt, dwFrameLines,
								m_pInsBuffer);
			break;
		default: ASSERT(0);
	}								
	
	EndWaitCursor();
	
	if (nRet == -1) AfxMessageBox("Escape by user!");
									
	m_wFrameLines=WORD(dwFrameLines);
}

/****************************************************************************
**
**  Name: CTraceWindow::DrawStatic
**
**  Description: 
**  Parameters:
**     input:   
**     output:	 
**
**  Return data:
**
****************************************************************************/
void CTraceWindow::DrawStatic(LPCSTR lpszText, UINT nCount,
								RECT rect, CDC* pDc)
{
COLORREF oldColor;
SIZE    size;
CPen    pen;
int     addx = m_nCharWidth/2-1;
int     addy;

	pDc->SelectStockObject(ANSI_FIXED_FONT);
	oldColor = pDc->SetBkColor(PALETTEINDEX(7));		//LTGRAY
	size = pDc->GetOutputTextExtent(lpszText, nCount);
	addy = (rect.bottom - rect.top - size.cy) / 2;
	pDc->ExtTextOut(rect.left+addx, rect.top+addy,
		ETO_CLIPPED | ETO_OPAQUE,
		&rect,
		lpszText,
		nCount,
		NULL);
	pDc->SetBkColor(oldColor);
	pDc->SelectStockObject(WHITE_PEN);
	pDc->MoveTo((rect.right-3),rect.top);       //               _
	pDc->LineTo((rect.left+1),rect.top);        //white line	|
	pDc->LineTo((rect.left+1),(rect.bottom-1));
	pen.CreatePen(PS_SOLID,1,PALETTEINDEX(12));	//darkgrey
	pDc->SelectObject(&pen);
	pDc->MoveTo((rect.right-2),rect.top);
	pDc->LineTo((rect.right-2),(rect.bottom-2));    //darkgrey line _|
	pDc->LineTo(rect.left,(rect.bottom-2));
	pDc->SelectStockObject(BLACK_PEN);    
	pDc->MoveTo((rect.right-1),rect.top);
	pDc->LineTo((rect.right-1),(rect.bottom-1));    //black line _|
	pDc->LineTo(rect.left-1,(rect.bottom-1));
}

/****************************************************************************
**
**  Name: CTraceWindow::ShowTitle
**
**  Description: Show first line of trace window, rely on m_nLeftfrom,
**				 m_nColnum and m_cdData.
**  Parameters:
**     input:   
**     output:	 
**
**  Return data:
**
****************************************************************************/
void CTraceWindow::ShowTitle(CPaintDC* pdc)
{
int		i;
RECT	rect;

	rect.top = 0;
	rect.bottom = m_nTitleHeight-1;
	rect.right=0;
	for(i=0; i<m_nColnum&&rect.right<=m_nPrevcx; i++)
	{
		rect.left = m_nLeftfrom+m_cdData[i].nPosx;
//		if((i==m_nColnum-1)&&!m_bHscOn)
//			rect.right=m_nPrevcx;
//		else
		rect.right = rect.left + m_cdData[i].nWidth;
		DrawStatic(m_cdData[i].strTitle, m_cdData[i].strTitle.GetLength(),
					rect, pdc);
	}
	if(rect.right<m_nPrevcx)
	{
		rect.left=rect.right;
		rect.right=m_nPrevcx+2;
		DrawStatic(NULL, 0, rect, pdc);
	}
}

/****************************************************************************
**
**  Name: CTraceWindow::ShowLine
**
**  Description: 
**  Parameters:
**     input:   
**     output:	 
**
**  Return data:
**
****************************************************************************/
void CTraceWindow::ShowLine(int y, int lineno, CPaintDC* pdc)
{
RECT	rect;
int		x=m_nLeftfrom+m_nCharWidth/2-1;

	rect.top=y;
	rect.bottom=y+m_nLineHeight-1;
	rect.left=x;
	rect.right=x+m_cdData[0].nWidth;

	switch(nTraceViewOption){
		case TRACEMODE_BUS:
			pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
					&rect,m_pBusBuffer[lineno].frameNo, 4, NULL);

			x= rect.left = rect.right;
			rect.right = rect.left+m_cdData[1].nWidth;
			pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
					&rect,m_pBusBuffer[lineno].addr, 7, NULL);

			x= rect.left = rect.right;
			rect.right = rect.left+m_cdData[2].nWidth;
			pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
					&rect,m_pBusBuffer[lineno].data, 4, NULL);

			x= rect.left = rect.right;
			rect.right = rect.left+m_cdData[3].nWidth;
			pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
					&rect,m_pBusBuffer[lineno].status, 2, NULL);

			x= rect.left = rect.right;
			//	rect.right = rect.left+m_cdData[4].nWidth;
			rect.right=m_nPrevcx;
			pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
					&rect,m_pBusBuffer[lineno].spare, 5, NULL);

			//	x= rect.left = rect.right;
			//	rect.right=m_nPrevcx;
			//	pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
			//					&rect,m_pBusBuffer[lineno].portdata, 2, NULL);
			break;
		case TRACEMODE_INSTRUCTION:
			pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
					&rect,m_pInsBuffer[lineno].frameNo, 4, NULL);

			x= rect.left = rect.right;
			rect.right = rect.left+m_cdData[1].nWidth;
			pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
					&rect,m_pInsBuffer[lineno].addr, 7, NULL);

			x= rect.left = rect.right;
			rect.right = rect.left+ 50*m_nCharWidth;// m_cdData[2].nWidth;
			pdc->ExtTextOut(x, y, ETO_CLIPPED|ETO_OPAQUE,
					&rect,m_pInsBuffer[lineno].instruction, 
					strlen(m_pInsBuffer[lineno].instruction), NULL);
			
			break;
	}					
}

/****************************************************************************
**
**  Name: CTraceWindow::RepaintLine
**
**  Description: 
**  Parameters:
**     input:   
**     output:	 
**
**  Return data:
**
****************************************************************************/
void CTraceWindow::RepaintLine(int nLine)
{
RECT rect;

	rect.top=nLine*m_nLineHeight+m_nTitleHeight;
	rect.bottom=rect.top+m_nLineHeight;
	rect.left=0;
	rect.right=m_nPrevcx;

	InvalidateRect(&rect, TRUE);
	UpdateWindow();
}

/****************************************************************************
**
**  Name: CTraceWindow::SetWindowTitle
**
**  Description: 
**  Parameters:
**     input:   
**     output:	 
**
**  Return data:
**
****************************************************************************/
void CTraceWindow::SetWindowTitle(UINT nPos)
{
char title[40];

	GetWindowText(title, 39);
	title[11]=NULL;
	if(nPos!=0xf012)
		wsprintf(&title[11]," - %04X", nPos);
    SetWindowText(title);
}

/****************************************************************************
**
**  Name: CTraceWindow::OnModeChange
**
**  Description:                 
**  Parameters:
**     input:   
**     output:	 
**
**  Return data:
**
****************************************************************************/
void CTraceWindow::OnModeChange()
{
	if(m_bCurSorLink)
		m_bCurSorLink=FALSE;
	else
	{
		m_bCurSorLink=TRUE;
		m_wCLLineIndex=0;
	}
	if(m_bCurSorLink)
		CLShowSrc();
	else
		SrcCursorLinkOff();
}

/****************************************************************************
**
**  Name: CTraceWindow::CLShowSrc
**
**  Description: 
**  Parameters:
**     input:   
**     output:	 
**
**  Return data:
**
****************************************************************************/
void CTraceWindow::CLShowSrc(void)
{
	ASSERT(m_bCurSorLink);              
	ASSERT(nTraceViewOption == TRACEMODE_INSTRUCTION);
//	ASSERT(m_wCLLineIndex<m_wFrameLines);
	if (m_wFrameLines==0) return;
	if (m_wCLLineIndex>=m_wFrameLines) m_wCLLineIndex = m_wFrameLines-1;
	
//static DWORD sdwAddr;
ADDRESS address;

//	if(sdwAddr==m_pBusBuffer[m_wCLLineIndex].dwAddr)
//		return;         
/*
	address.adrSpace=(m_pBusBuffer[m_wCLLineIndex].dwAddr>>16)+SPACE_P0;
	address.adrAddress=m_pBusBuffer[m_wCLLineIndex].dwAddr&0xffff;
	SrcCursorLink(address.adrAddress, address.adrSpace);
	sdwAddr=m_pBusBuffer[m_wCLLineIndex].dwAddr;
*/
	address.adrSpace=(m_pInsBuffer[m_wCLLineIndex].dwAddr>>16)+SPACE_P0;
	address.adrAddress=m_pInsBuffer[m_wCLLineIndex].dwAddr&0xffff;
	SrcCursorLink(address.adrAddress, address.adrSpace);
//	sdwAddr=m_pInsBuffer[m_wCLLineIndex].dwAddr;
}

BEGIN_MESSAGE_MAP(CTraceWindow, CMDIChildWnd)
	//{{AFX_MSG_MAP(CTraceWindow)
	ON_WM_CREATE()
	ON_WM_SIZE()
	ON_WM_PAINT()
	ON_WM_HSCROLL()
	ON_WM_VSCROLL()
	ON_WM_KEYDOWN()
	ON_WM_RBUTTONDOWN()
	ON_COMMAND(ID_VIEW_REFRESH, OnViewRefresh)
	ON_COMMAND(ID_EDIT_GOTOSTARTFRAME, OnEditGotostartframe)
	ON_COMMAND(ID_EDIT_GOTOENDFRAME, OnEditGotoendframe)
	ON_COMMAND(ID_EDIT_GOTOFRAME, OnEditGotoframe)
	ON_COMMAND(ID_FILE_SAVETRACE, OnFileSavetrace)
	ON_COMMAND(ID_TRACE_FILTER, OnTraceFilter)
	ON_WM_LBUTTONDOWN()
	ON_COMMAND(ID_TRACE_EVENT, OnTraceEvent)
	ON_COMMAND(ID_TRACE_CONTROL, OnTraceControl)
	ON_COMMAND(ID_TRACE_CLEAR, OnTraceClear)
	ON_UPDATE_COMMAND_UI(ID_TRACE_CLEAR, OnUpdateTraceClear)
	ON_COMMAND(ID_TRACE_TRIGGER, OnTraceTrigger)
	ON_COMMAND(ID_VIEW_CURSORLINK, OnViewCursorlink)
	ON_UPDATE_COMMAND_UI(ID_VIEW_CURSORLINK, OnUpdateViewCursorlink)
	ON_WM_MDIACTIVATE()
	ON_COMMAND(ID_VIEW_BUS, OnViewBus)
	ON_UPDATE_COMMAND_UI(ID_VIEW_BUS, OnUpdateViewBus)
	ON_COMMAND(ID_VIEW_INSTRUCTION, OnViewInstruction)
	ON_UPDATE_COMMAND_UI(ID_VIEW_INSTRUCTION, OnUpdateViewInstruction)
	ON_COMMAND(ID_EDIT_SEARCH, OnEditSearch)
	ON_UPDATE_COMMAND_UI(ID_EDIT_SEARCH, OnUpdateEditSearch)
	ON_COMMAND(ID_EDIT_SEARCHNEXT, OnEditSearchnext)
	ON_UPDATE_COMMAND_UI(ID_EDIT_SEARCHNEXT, OnUpdateEditSearchnext)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CTraceWindow message handlers


int CTraceWindow::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
TEXTMETRIC	tm;

	CDC* pdc=GetDC();
	pdc->SelectStockObject(ANSI_FIXED_FONT);
	pdc->GetTextMetrics(&tm);
	ReleaseDC(pdc);
	m_nCharWidth=tm.tmAveCharWidth;
	m_nLineHeight=tm.tmHeight+tm.tmExternalLeading+1;
	SetColData();
	return 0;
}

void CTraceWindow::OnSize(UINT nType, int cx, int cy)
{
	CMDIChildWnd::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
WORD	wLines;

	m_bIconic=(nType==SIZE_MINIMIZED);
	if(m_bIconic)
		return;
    
	if(m_nPrevcx!=cx)
	{
		if(m_nLineWidth<=cx)
		{
			if(m_bHscOn)
			{
				m_bHscOn=FALSE;
				m_nLeftfrom=0;
				ShowScrollBar(SB_HORZ, FALSE);
				return;
			}
		}
		else 
		{
			if(!m_bHscOn)
			{
				m_bHscOn=TRUE;
				ShowScrollBar(SB_HORZ);
				return;
			}
			m_nHscMaxpos=m_nLineWidth-cx;
			SetScrollRange(SB_HORZ,0,m_nHscMaxpos,FALSE);
			if(-m_nLeftfrom>m_nHscMaxpos)
				m_nLeftfrom=-m_nHscMaxpos;
			SetScrollPos(SB_HORZ, -m_nLeftfrom, TRUE);
		}
		m_nPrevcx=cx;
	}
	if(m_nPrevcy!=cy)
	{
		wLines=WORD(max(0, cy-m_nTitleHeight+m_nLineHeight-1)/m_nLineHeight);
		if((DWORD)wLines>m_dwLastFrame+1)	//m_wLines not include title
		{
			if(m_bVscOn)
			{
				m_dwCurFrame=0; 
				m_byCurInt = 0;
				m_bVscOn=FALSE;
				ShowScrollBar(SB_VERT, FALSE);
				return;
			}
		}
		else
		{
			if(!m_bVscOn||m_nPrevcy==0xffff)
			{
				m_nPrevcy=0;
				m_bVscOn=TRUE;
				ShowScrollBar(SB_VERT);
				SetScrollRange(SB_VERT, 0, int(m_dwLastFrame/m_nScrUnit), FALSE);
				m_dwCurFrame=min(m_dwCurFrame, m_dwLastFrame);
				SetScrollPos(SB_VERT, int(m_dwCurFrame/m_nScrUnit), TRUE);
				return;
			}
		}
		if(wLines>m_wLines)
		{
			m_wLines=wLines;
			m_nReadDirect=0;
			PrepareData();
		}
		else
		{
			m_wFrameLines=min(m_wFrameLines, wLines);
			if(m_bCurSorLink&&m_wCLLineIndex>m_wFrameLines-CL_DISCARDLINENUM)
			{
				m_wCLLineIndex=m_wFrameLines-CL_DISCARDLINENUM;
				CLShowSrc();
				RepaintLine(m_wCLLineIndex);
				RepaintLine(m_wCLLineIndex+1);
			}
		}
		m_wLines=wLines;
		m_nPrevcy=cy;
	}
}

void CTraceWindow::OnPaint()
{
	CPaintDC dc(this); // device context for painting

	// TODO: Add your message handler code here
int	i;
BOOL	bBCChange=FALSE;
COLORREF	crBackColor, crTextColor;

	if(m_bIconic)
		return;
	ShowTitle(&dc);
	for(i=0; i<int(m_wFrameLines); i++)
	{
		if(m_bCurSorLink&&int(m_wCLLineIndex)==i)
		{
			bBCChange=TRUE;
			crBackColor=dc.GetBkColor();
			dc.SetBkColor(PALETTEINDEX(16));		//yellow(see colors.h)
			crTextColor=dc.GetTextColor();
			dc.SetTextColor(PALETTEINDEX(15));
		}
		ShowLine(i*m_nLineHeight+m_nTitleHeight, i, &dc);
		if(bBCChange)
		{
			dc.SetBkColor(crBackColor);
			dc.SetTextColor(crTextColor);
			bBCChange=FALSE;
		}
	}
	if(m_wFrameLines<m_wLines)
	{      
		if (m_nPrevcy==0)
		{
			RECT	clientRect;
		    GetClientRect(&clientRect);
		    m_nPrevcy = clientRect.bottom;
		}


		CRect rect(0, i*m_nLineHeight+m_nTitleHeight, m_nPrevcx, m_nPrevcy);
		CBrush Brush;
		Brush.CreateSolidBrush(RGB(0xff,0xff,0xff));    //white
		dc.FillRect(&rect, &Brush);
		Brush.DeleteObject();
	}
	// Do not call CMDIChildWnd::OnPaint() for painting messages
}

void CTraceWindow::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* /*pScrollBar*/)
{
	// TODO: Add your message handler code here and/or call default
	if(!m_bHscOn)
		return;

int	old=-m_nLeftfrom;
	switch(nSBCode)
	{
		case SB_LINERIGHT:
			if(old>=m_nHscMaxpos)
				return;
			m_nLeftfrom-=m_nCharWidth;
			break;
		case SB_LINELEFT:
			if(old<=0)
				return;
			m_nLeftfrom+=m_nCharWidth;
			break;
		case SB_PAGERIGHT:
			if(old>=m_nHscMaxpos)
				return;
			m_nLeftfrom-=(m_nPrevcx-m_nCharWidth);
			break;
		case SB_PAGELEFT:
			if(old<=0)
				return;
			m_nLeftfrom+=(m_nPrevcx-m_nCharWidth);
			break;
		case SB_THUMBTRACK:
			if(nPos==(UINT)old)
				return;
	 		m_nLeftfrom=-int(nPos);
			break;
		default:
			return;
		}
	m_nLeftfrom=min(m_nLeftfrom, 0);
	m_nLeftfrom=max(m_nLeftfrom, -m_nHscMaxpos);
	if(m_nLeftfrom!=-old)
	{
		SetScrollPos(SB_HORZ, -m_nLeftfrom, TRUE);
		ScrollWindow(m_nLeftfrom+old, 0);
		//UpdateWindow();
		//Invalidate();
	}
//	CMDIChildWnd::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CTraceWindow::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* /*pScrollBar*/)
{
	// TODO: Add your message handler code here and/or call default
	if(!m_bVscOn)
		return;

	switch(nSBCode)
	{
		case SB_LINEUP:
			if(m_dwCurFrame<0 || (m_dwCurFrame==0 && m_byCurInt==0))
				return;
			m_nReadDirect=-1;
			break;
		case SB_LINEDOWN:
			if(m_dwCurFrame>m_dwLastFrame)
				return;
			m_nReadDirect=1;
			break;  
		case SB_PAGEUP:
			if(m_dwCurFrame<0 || (m_dwCurFrame==0 && m_byCurInt==0))
				return;
			m_nReadDirect=-2;               
			break;  
		case SB_PAGEDOWN:
			if(m_dwCurFrame>m_dwLastFrame)
				return;
			m_nReadDirect=2;
			break;
		case SB_TOP:
			if(m_dwCurFrame<0 || (m_dwCurFrame==0 && m_byCurInt==0))
				return;
			m_dwCurFrame=0;                 
			m_byCurInt = 0;
			m_nReadDirect=0;
			break;
		case SB_BOTTOM:
			if(m_dwCurFrame>m_dwLastFrame)
				return;
			m_dwCurFrame=m_dwLastFrame;
			m_nReadDirect=0;
			break;
		case SB_THUMBTRACK:
			SetWindowTitle(nPos*m_nScrUnit);
			return;
		case SB_THUMBPOSITION:
			SetWindowTitle(0xf012);
			if(nPos*m_nScrUnit==m_dwCurFrame && m_byCurInt==0)
				return;
			m_dwCurFrame=(WORD)nPos*m_nScrUnit;    
			if (m_byCurInt <= 1)  
				m_byCurInt = 0;
			else m_byCurInt = 1;
			m_nReadDirect=0;
			break;
		default:
			return;
	}
	PrepareData();			//now m_dwCurFrame is set to current pos.
	if(m_bCurSorLink)
		CLShowSrc();
	InvalidateRect(NULL, FALSE/*TRUE*/);     //use TRUE parament is too slow
	SetScrollPos(SB_VERT, int(m_dwCurFrame/m_nScrUnit), TRUE);
//	CMDIChildWnd::OnVScroll(nSBCode, nPos, pScrollBar);
}

void CTraceWindow::OnKeyDown(UINT nChar, UINT /*nRepCnt*/, UINT /*nFlags*/)
{
	// TODO: Add your message handler code here and/or call default
int bCtrl = GetKeyState(VK_CONTROL)&0x8000;

	switch(nChar)
	{
		case VK_HOME:
			SendMessage(WM_VSCROLL, SB_TOP, 0l);
			break;
		case VK_END:
			SendMessage(WM_VSCROLL, SB_BOTTOM, 0l);
			break;          
		case VK_PRIOR:
			SendMessage(WM_VSCROLL, SB_PAGEUP, 0l);
			break;                                 
		case VK_NEXT:
			SendMessage(WM_VSCROLL, SB_PAGEDOWN, 0l);
			break;
		case VK_UP:
			if(!bCtrl&&m_bCurSorLink&&m_wCLLineIndex>0)
			{
				m_wCLLineIndex--;
				CLShowSrc();
				RepaintLine(m_wCLLineIndex);
				RepaintLine(m_wCLLineIndex+1);
			}
			else
				SendMessage(WM_VSCROLL, SB_LINEUP, 0l);
			break;                                 
		case VK_DOWN:
		    if(!bCtrl&&m_bCurSorLink
		    	&&m_wCLLineIndex<m_wFrameLines-CL_DISCARDLINENUM
		    	&&m_wFrameLines>=CL_DISCARDLINENUM)
			{
				m_wCLLineIndex++;
				CLShowSrc();
				RepaintLine(m_wCLLineIndex);
				RepaintLine(m_wCLLineIndex-1);
			}
			else
				SendMessage(WM_VSCROLL, SB_LINEDOWN, 0l);
			break;                                   
		case VK_LEFT:
			SendMessage(WM_HSCROLL, SB_LINEUP, 0l);
			break;                                          
		case VK_RIGHT:
			SendMessage(WM_HSCROLL, SB_LINEDOWN, 0l);
			break;                                     
	}   
	return;
}


void CTraceWindow::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
int nLine;
WORD bak;
	if(point.y<=m_nTitleHeight||!m_bCurSorLink)
		return;
	nLine=(point.y-m_nTitleHeight)/m_nLineHeight;
	if(nLine>m_wFrameLines-CL_DISCARDLINENUM||nLine==m_wCLLineIndex)
		return;
	bak=m_wCLLineIndex;
	m_wCLLineIndex=nLine;
	CLShowSrc();
	RepaintLine(m_wCLLineIndex);
	RepaintLine(bak);
	CMDIChildWnd::OnLButtonDown(nFlags, point);
}

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

	pLocalMenu->CreatePopupMenu();
	pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_REFRESH, "&Refresh");
	pLocalMenu->AppendMenu(MF_STRING, ID_TRACE_CLEAR, "C&lear");
	pLocalMenu->AppendMenu(MF_SEPARATOR);    
	pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_BUS, "&Bus");
	pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_INSTRUCTION, "&Instruction");
	pLocalMenu->AppendMenu(MF_SEPARATOR);
	pLocalMenu->AppendMenu(MF_STRING, ID_VIEW_CURSORLINK,
							"&Cursor Link");
	pLocalMenu->AppendMenu(MF_SEPARATOR);
	pLocalMenu->AppendMenu(MF_STRING, ID_EDIT_GOTOSTARTFRAME,
							"Goto &Start Frame");
	pLocalMenu->AppendMenu(MF_STRING, ID_EDIT_GOTOENDFRAME, "Goto &End Frame");
	pLocalMenu->AppendMenu(MF_STRING, ID_EDIT_GOTOFRAME, "&Goto Frame...");
	pLocalMenu->AppendMenu(MF_STRING, ID_EDIT_SEARCH, "&Search...");
	pLocalMenu->AppendMenu(MF_STRING, ID_EDIT_SEARCHNEXT, "Search &Next	F4");
	pLocalMenu->AppendMenu(MF_SEPARATOR);
	pLocalMenu->AppendMenu(MF_STRING, ID_FILE_SAVETRACE, "S&ave Trace...");
	pLocalMenu->AppendMenu(MF_SEPARATOR);
	pLocalMenu->AppendMenu(MF_STRING, ID_TRACE_CONTROL, "Trace &Control...");
	pLocalMenu->AppendMenu(MF_STRING, ID_TRACE_EVENT, "E&vent...");
	pLocalMenu->AppendMenu(MF_STRING, ID_TRACE_TRIGGER, "&Trigger...");
	pLocalMenu->AppendMenu(MF_STRING, ID_TRACE_FILTER, "Trace &Filter...");

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

	CMDIChildWnd::OnRButtonDown(nFlags, point);
}

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

//	if(bCtrl)
//		ResetTraceBuf(-1);
	m_nReadDirect=0;
	PrepareData();
	InvalidateRect(NULL, TRUE);
}

void CTraceWindow::OnEditGotostartframe()
{
	// TODO: Add your command handler code here
	SendMessage(WM_VSCROLL, SB_TOP, 0);
}

void CTraceWindow::OnEditGotoendframe()
{
	// TODO: Add your command handler code here
	SendMessage(WM_VSCROLL, SB_BOTTOM, 0);

}

void CTraceWindow::OnEditGotoframe()
{
	// TODO: Add your command handler code here
HINSTANCE hLib;

CTrcGtdlg dlg(this);
int result = dlg.DoModal();

	if (result!=IDOK)
		return;
	if(dlg.dwGotoFrame>m_dwLastFrame)
		dlg.dwGotoFrame=m_dwLastFrame;
	SendMessage(WM_VSCROLL, SB_THUMBPOSITION, LPARAM(dlg.dwGotoFrame));
}

void CTraceWindow::OnFileSavetrace()
{
	// TODO: Add your command handler code here
HINSTANCE hLib;
WORD topFrame,bottomFrame;
WORD count, inc;      
BOOL Isreadonly=FALSE;
CString filename;

//	if ((hLib = LoadLibrary("MUSCROLL.DLL")) < HINSTANCE_ERROR)
//	{
//		AfxMessageBox("Can't find MUSCROLL.DLL");
//		i = 0;
//	}
	CTrcFiDlg dlg(this);
	count = WORD(dlg.DoModal());
	if (count!=IDOK)
		return;
	if(dlg.GetReadOnlyPref())						//by chris.
		Isreadonly=TRUE;
	filename=dlg.GetPathName();  
	
	BeginWaitCursor();
	TS_SaveTraceToFile(nTraceViewOption, filename, dlg.m_dwSaveStart,
					dlg.m_dwSaveEnd, TRUE);
	EndWaitCursor();					

//	if(i) FreeLibrary(hLib);
}

void CTraceWindow::OnTraceEvent()
{
	// TODO: Add your command handler code here
	CTraceGroupDialog dlg(AfxGetApp()->m_pMainWnd, 0);
	dlg.DoModal();
	if(dlg.m_bDisplayChange){
		MSG msg;
		while (PeekMessage(&msg, dlg.m_hWnd, 0, 0, PM_REMOVE)) {
		    TranslateMessage(&msg);
		    DispatchMessage(&msg);
		}
		
		SendMessage(WM_COMMAND,ID_VIEW_REFRESH, NULL);
	}
}

void CTraceWindow::OnTraceControl()
{
	// TODO: Add your command handler code here
	CTraceGroupDialog dlg(AfxGetApp()->m_pMainWnd,1);
	dlg.DoModal();
	if(dlg.m_bDisplayChange){
		MSG msg;
		while (PeekMessage(&msg, dlg.m_hWnd, 0, 0, PM_REMOVE)) {
		    TranslateMessage(&msg);
		    DispatchMessage(&msg);
		}
	
		SendMessage(WM_COMMAND,ID_VIEW_REFRESH, NULL);
	}
}

void CTraceWindow::OnTraceTrigger()
{
	// TODO: Add your command handler code here
	CTraceGroupDialog dlg(AfxGetApp()->m_pMainWnd,2);
	dlg.DoModal();
	if(dlg.m_bDisplayChange){
		MSG msg;
		while (PeekMessage(&msg, dlg.m_hWnd, 0, 0, PM_REMOVE)) {
		    TranslateMessage(&msg);
		    DispatchMessage(&msg);
		}
	
		SendMessage(WM_COMMAND,ID_VIEW_REFRESH, NULL);
	}
}

void CTraceWindow::OnTraceFilter()
{
	// TODO: Add your command handler code here
	CTraceGroupDialog dlg(AfxGetApp()->m_pMainWnd,3);
	dlg.DoModal();
	if(dlg.m_bDisplayChange){
		MSG msg;
		while (PeekMessage(&msg, dlg.m_hWnd, 0, 0, PM_REMOVE)) {
		    TranslateMessage(&msg);
		    DispatchMessage(&msg);
		}
	
		SendMessage(WM_VSCROLL, SB_THUMBPOSITION, LPARAM(0));
		SendMessage(WM_COMMAND,ID_VIEW_REFRESH, NULL);
	}
}

void CTraceWindow::OnTraceClear()
{
	// TODO: Add your command handler code here
	TS_TraceClear();
	OnViewRefresh();
}

void CTraceWindow::OnUpdateTraceClear(CCmdUI* pCmdUI)
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(!IsTraceClear());
}

void CTraceWindow::OnViewCursorlink()
{
	// TODO: Add your command handler code here
	ASSERT(nTraceViewOption==TRACEMODE_INSTRUCTION);
	
	OnModeChange();
	InvalidateRect(NULL, TRUE);
}

void CTraceWindow::OnUpdateViewCursorlink(CCmdUI* pCmdUI)
{
	// TODO: Add your command update UI handler code here
    if (::GetCpuStatus2() == STATUS_HALT && m_dwLastFrame!=0
    	&& nTraceViewOption==TRACEMODE_INSTRUCTION) 
    	pCmdUI->Enable(TRUE);
    else{
    	pCmdUI->Enable(FALSE);
    	return;
    }
	
	if(!::SrcIsBrowseWindowOpened()&&m_bCurSorLink)
		OnViewCursorlink();                       

	pCmdUI->SetCheck(m_bCurSorLink);
	
/*			
	if(m_bCurSorLink)
		pCmdUI->SetCheck(TRUE);
	else
	{
		pCmdUI->SetCheck(FALSE);
		if(m_dwLastFrame==0)
			pCmdUI->Enable(FALSE);
	}
*/	
}

void CTraceWindow::OnMDIActivate(BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd)
{
	CMDIChildWnd::OnMDIActivate(bActivate, pActivateWnd, pDeactivateWnd);
	
	// TODO: Add your message handler code here
    if(bActivate && pActivateWnd == this) {
        /*AfxGetApp()->m_pMainWnd*/
        GetMDIFrame()->SendMessage(XM_MDIACTIVE, WORD(bActivate),
            LONG(WID_TRACE));
        //GotoCursor();
    }
    else if(!bActivate && !pActivateWnd)
        /*AfxGetApp()->m_pMainWnd*/
        GetMDIFrame()->SendMessage(XM_MDIACTIVE, WORD(bActivate));
	
}


void CTraceWindow::OnViewBus()
{
	// TODO: Add your command handler code here               
	if (nTraceViewOption != TRACEMODE_BUS){
		nTraceViewOption = TRACEMODE_BUS;
		
		if (m_bCurSorLink){
			m_bCurSorLink=FALSE;
			SrcCursorLinkOff();
		}	            

		SetColData();
		OnViewRefresh();
	}
}

void CTraceWindow::OnUpdateViewBus(CCmdUI* pCmdUI)
{
	// TODO: Add your command update UI handler code here
//	pCmdUI->Enable(TRUE);
	pCmdUI->SetCheck(nTraceViewOption==TRACEMODE_BUS);	
}

void CTraceWindow::OnViewInstruction()
{
	// TODO: Add your command handler code here
	if (nTraceViewOption != TRACEMODE_INSTRUCTION){
		nTraceViewOption = TRACEMODE_INSTRUCTION;
		
		SetColData();
		OnViewRefresh();
	}	
}

void CTraceWindow::OnUpdateViewInstruction(CCmdUI* pCmdUI)
{
	// TODO: Add your command update UI handler code here
//	pCmdUI->Enable(TRUE);	                          
	pCmdUI->SetCheck(nTraceViewOption==TRACEMODE_INSTRUCTION);
}

void CTraceWindow::OnEditSearch()
{
	// TODO: Add your command handler code here
    long result;
    CTrcSchDg dlg(this, nTraceViewOption);

    result = dlg.DoModal();
    
    if (result!=1) return;     

	MSG msg;
	while (PeekMessage(&msg, dlg.m_hWnd, 0, 0, PM_REMOVE)) {
	    TranslateMessage(&msg);
	    DispatchMessage(&msg);
	}

    g_bCanSearchNext = TRUE;

	BeginWaitCursor();
	
    switch (nTraceViewOption)
    {

        case TRACEMODE_INSTRUCTION:
            result = SearchIns(0);
            EndWaitCursor();
            if (result<-1)
            {
                char info[50];
                sprintf(info, "Break by User at frame 0x%lX !", -result);
                MessageBox(info,"Search",MB_OK|MB_ICONHAND|MB_ICONSTOP);
                break;
            }
            if (result==-1) 
            {
                MessageBox("String Not Found!","Search",MB_OK|MB_ICONHAND|MB_ICONSTOP);
                break;
            }
            SendMessage(WM_VSCROLL, SB_THUMBPOSITION, LPARAM(result));
            break;

        case TRACEMODE_BUS:
            result = SearchBus(0);
            EndWaitCursor();
            if (result<-1)
            {
                char info[50];
                sprintf(info, "Break by User at frame 0x%lX !", -result);
                MessageBox(info,"Search",MB_OK|MB_ICONHAND|MB_ICONSTOP);
                break;
            }
            if (result==-1) 
            {
                MessageBox("String Not Found!","Search",MB_OK|MB_ICONHAND|MB_ICONSTOP);
                break;
            }
            SendMessage(WM_VSCROLL, SB_THUMBPOSITION, LPARAM(result));
            break;                      
     }                        
     
	UpdateStatusBar(0, "");

}

void CTraceWindow::OnUpdateEditSearch(CCmdUI* pCmdUI)
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(m_dwLastFrame > 0);	
}

void CTraceWindow::OnEditSearchnext()
{
	// TODO: Add your command handler code here
    long result;

	BeginWaitCursor();
	
    switch (nTraceViewOption)                        	
    {

        case TRACEMODE_INSTRUCTION:
            result = SearchIns(1);
            EndWaitCursor();
            if (result<-1)
            {
                char info[50];
                sprintf(info, "Break by User at frame 0x%lX !", -result);
                MessageBox(info,"Search",MB_OK|MB_ICONHAND|MB_ICONSTOP);
                break;
            }
            if (result==-1) 
            {
                MessageBox("String Not Found!","Search",MB_OK|MB_ICONHAND|MB_ICONSTOP);
                break;
            }
            SendMessage(WM_VSCROLL, SB_THUMBPOSITION, LPARAM(result));
            break;

        case TRACEMODE_BUS:
            result = SearchBus(1);
            EndWaitCursor();
            if (result<-1)
            {
                char info[50];
                sprintf(info, "Break by User at frame 0x%lX !", -result);
                MessageBox(info,"Search",MB_OK|MB_ICONHAND|MB_ICONSTOP);
                break;
            }
            if (result==-1) 
            {
                MessageBox("String Not Found!","Search",MB_OK|MB_ICONHAND|MB_ICONSTOP);
                break;
            }
            SendMessage(WM_VSCROLL, SB_THUMBPOSITION, LPARAM(result));
            break;                      
     }
	UpdateStatusBar(0, "");
	
}

void CTraceWindow::OnUpdateEditSearchnext(CCmdUI* pCmdUI)
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(m_dwLastFrame > 0 && ::g_bCanSearchNext);	
}


extern int  TestKey(WORD);

long CTraceWindow::SearchBus(int begin)
{
    ASSERT(g_nTrcSearchMode != 0);
    
    DWORD firstNo, i;
    DWORD dwFrameNo = 10;    
    char *find = NULL;
    
    FrameData* ptrBuf;
    FrameData* buf = new FrameData[10];

    ASSERT(buf!=NULL);
    
    firstNo = m_dwCurFrame + (DWORD)begin;

	int nReturn; 
	char szCurInfo[100];
    while(firstNo < m_dwLastFrame)
    {
		if(TestKey(VK_ESCAPE))
        {
        	delete [] buf;
        	return (-(long)firstNo);
        }
		
//		wsprintf(szCurInfo, "Read frame from %lX", firstNo);
//		ShowMsgToStatusBar(szCurInfo);
		ShowReadTraceCurSite(firstNo);

		if ( (nReturn = TS_GetBusRecord(0, firstNo, dwFrameNo, buf)) < 0)
		{
			delete [] buf;
			return (-(long)firstNo);
		}
		

		wsprintf(szCurInfo, "Search trace from 0X%lX", firstNo);
		ShowMsgToStatusBar(szCurInfo);
		
        ptrBuf = buf;
        for(i=0;i<dwFrameNo;i++)
        {                         
        	if (g_nTrcSearchMode & CTrcSchDg::SEARCH_FRAME)
        	{
            	find = strstr(ptrBuf->frameNo, g_trcSearchContent);
            	if (find!=NULL)
                	break;
            }
            
        	if (g_nTrcSearchMode & CTrcSchDg::SEARCH_ADDRESS)
        	{
	            find = strstr(ptrBuf->addr, g_trcSearchContent);
	            if (find!=NULL)
	                break;
	         }
	         
            
        	if (g_nTrcSearchMode & CTrcSchDg::SEARCH_DATA)
        	{
	         
	            find = strstr(ptrBuf->data, g_trcSearchContent);
	            if (find!=NULL)
	                break;   
	        }
	        
        	if (g_nTrcSearchMode & CTrcSchDg::SEARCH_STATUS)
        	{
	            find = strstr(ptrBuf->status, g_trcSearchContent);
	            if (find!=NULL)
	                break;
	        }
	        
        	if (g_nTrcSearchMode & CTrcSchDg::SEARCH_SPARE)
        	{
	            find = strstr(ptrBuf->spare, g_trcSearchContent);
	            if (find!=NULL)
	                break;
	        }
	        
            ptrBuf++;
        }


        if (find!=NULL) 
        {
        	firstNo=ptrBuf->physicalNo;
        	break;
        } 
        
        if (dwFrameNo < 10)
        	break;
        else firstNo = buf[dwFrameNo-1].physicalNo+1;

    }
    
    delete buf;
    
    if (find!=NULL) return (long)firstNo;
    else return(-1);
}               

long CTraceWindow::SearchIns(int begin)
{
    ASSERT(g_nTrcSearchMode != 0);
    ASSERT(begin==0 || begin==1);
    
    DWORD firstNo, i;
    DWORD dwFrameNo = 11;    
    BYTE  byInt;
    
    char *find = NULL;
    
    InsData* ptrBuf;
    InsData* buf = new InsData[11];

    ASSERT(buf!=NULL);

	firstNo = m_dwCurFrame; 
	byInt = m_byCurInt;
	
	if (begin > 0)   
	{
		if (byInt > 0)
		{
			byInt = 0;
			firstNo ++;
		}
		else byInt ++;
	}

	BOOL bFirst = TRUE;
		
    while(firstNo < m_dwLastFrame)
    {
		if(TestKey(VK_ESCAPE))
        {
        	delete [] buf;
        	return (-(long)firstNo);
        }
        
        char szCurInfo[100];
        
		ShowReadTraceCurSite(firstNo);
				
		if (TS_GetInsRecord(0, firstNo, byInt, dwFrameNo, buf) < 0)
		{
			delete [] buf;
			return (-(long)firstNo);
		}
	
		wsprintf(szCurInfo, "Search trace from 0X%lX", firstNo);
		ShowMsgToStatusBar(szCurInfo);
			
        ptrBuf = buf;
        for(i=bFirst? (DWORD)begin : 1; i<dwFrameNo;i++)
        {                         
        	if (g_nTrcSearchMode & CTrcSchDg::SEARCH_FRAME)
        	{
            	find = strstr(ptrBuf->frameNo, g_trcSearchContent);
            	if (find!=NULL)
                	break;
            }
            
        	if (g_nTrcSearchMode & CTrcSchDg::SEARCH_ADDRESS)
        	{
	            find = strstr(ptrBuf->addr, g_trcSearchContent);
	            if (find!=NULL)
	                break;
	         }
	         
            
        	if (g_nTrcSearchMode & CTrcSchDg::SEARCH_INSTRUCTION)
        	{
	            find = strstr(ptrBuf->instruction, g_trcSearchContent);
	            if (find!=NULL)
	                break;
	        }
	        
            ptrBuf++;
        }


        if (find!=NULL) 
        {
        	firstNo=ptrBuf->physicalNo;       
        	m_byCurInt = ptrBuf->intNo;
// modify for search bugs 17/10/97
			if (m_byCurInt > 0) m_byCurInt += 4;        	
        	break;
        } 
        
        if (dwFrameNo < 11)
        	break;
        else{   
        	firstNo = buf[dwFrameNo-1].physicalNo;
        	byInt = buf[dwFrameNo-1].intNo;
         }                          
         
         bFirst = FALSE;
    }                                                         
    
    delete buf;
    
    if (find!=NULL) return (long)firstNo;
    else return(-1);
}


/******************************end of file*******************************/