⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 integerdatapathctrl.cpp

📁 一个牛人做的MIPS模拟器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// IntegerDatapathCtrl.cpp : implementation file
//

#include "stdafx.h"
#include "pipeline.h"
#include "IntegerDatapathCtrl.h"
#include "MIPSSimulator.h"

#include "MemDlg.h"
#include "RegDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CIntegerDatapathCtrl

CIntegerDatapathCtrl::CIntegerDatapathCtrl()
{
	m_penStyle = PS_SOLID;
	m_penWidth = 1;
	m_penColor = RGB( 0, 0, 0 );
	m_regColor = RGB( 200, 200, 200 );
	m_bkColor = RGB( 230, 230, 250 );
}

CIntegerDatapathCtrl::~CIntegerDatapathCtrl()
{
	if(memDC.GetSafeHdc() != NULL)
	{
		memDC.SelectObject( m_pOldBitmap );
		if( m_pBitmap != NULL )
			delete m_pBitmap;

		memDC.SelectObject( m_pOldFont );
	}
}


BEGIN_MESSAGE_MAP(CIntegerDatapathCtrl, CWnd)
	//{{AFX_MSG_MAP(CIntegerDatapathCtrl)
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CIntegerDatapathCtrl message handlers

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

	if( memDC.GetSafeHdc() != NULL )
		dc.BitBlt( 0, 0, rcClient.Width(), rcClient.Height(), &memDC, 0, 0, SRCCOPY );
}

BOOL CIntegerDatapathCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd)
{
	m_pParentWnd = pParentWnd;

	// create window
	static CString className = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,AfxGetApp()->LoadStandardCursor(IDC_ARROW));
	BOOL ret = CWnd::CreateEx( NULL, className, NULL, dwStyle, 
		rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
		pParentWnd->GetSafeHwnd(), 0);
	// init virtual screen
	GetClientRect( rcClient );
	CClientDC dc( this );
	if( memDC.GetSafeHdc() == NULL ) {
		memDC.CreateCompatibleDC( &dc );

		if( (m_pBitmap = new CBitmap()) == NULL ) return FALSE;
		m_pBitmap->CreateCompatibleBitmap( &dc, rcClient.Width(), rcClient.Height() );	
		m_pOldBitmap = memDC.SelectObject( m_pBitmap );

		CFont NewFont;
		NewFont.CreateFont( -9, 0, 0, 0, FW_SEMIBOLD, 0, 0,
			0, 134, 3, 2, 1, 2, "Microsoft Sans Serif" );
		m_pOldFont = memDC.SelectObject( &NewFont );
		memDC.SetBkMode( TRANSPARENT );// use TRANSPARENT
	}

	memDC.FillSolidRect( &rcClient, m_bkColor );
	InitLines();
	DrawAll();

	return ret;
}

void CIntegerDatapathCtrl::Reset()
{
	RestoreIFLines( FALSE );
	RestoreIDLines( FALSE );
	RestoreEXLines( FALSE );
	RestoreMEMLines( FALSE );
	RestoreWBLines( FALSE );
	
	DrawAll();
	Invalidate();
}

void CIntegerDatapathCtrl::NextCycle( BOOL bRedraw )
{
	Reset();

	CExecInst* next = simulator.m_pExecInsts->next;
	while( next ) {
		if( next->m_nLastStage == IF && next->pInst->m_key != IDLE_INST )
			IFLines( PS_SOLID, 3, next->color, next->pInst->InstString() );
		else if( next->m_nLastStage == ID && next->pInst->m_key != IDLE_INST )
			IDLines( PS_SOLID, 3, next->color, next->pInst->InstString() );
		else if( next->m_nLastStage == EX && next->pInst->m_key != IDLE_INST &&
			next->pInst->m_key != MUL && next->pInst->m_key != MUT &&
			next->pInst->m_key != DIV && next->pInst->m_key != MULI	&&
			next->pInst->m_key != MUTI && next->pInst->m_key != DIVI )
			EXLines( PS_SOLID, 3, next->color, next->pInst->InstString() );
		else if( next->m_nLastStage == MEM && next->pInst->m_key != IDLE_INST &&
			next->pInst->m_key != MUL && next->pInst->m_key != MUT &&
			next->pInst->m_key != DIV && next->pInst->m_key != MULI	&&
			next->pInst->m_key != MUTI && next->pInst->m_key != DIVI )
			MEMLines( PS_SOLID, 3, next->color, next->pInst->InstString() );
		else if( next->m_nLastStage == WB && next->pInst->m_key != IDLE_INST &&
			next->pInst->m_key != SW )
			WBLines( PS_SOLID, 3, next->color, next->pInst->InstString() );

		next = next->next;
	}

	if( bRedraw ) Invalidate();
}

/********************************************************
 * draw circuits
 ********************************************************/
void CIntegerDatapathCtrl::InitLines()
{
	// IF
	CRect rect;
	l1.PolyAdd( 40, 165 ); l1.PolyAdd( 72, 165 );

	l2.PolyAdd( 47, 165 ); l2.PolyAdd( 47, 138 ); l2.PolyAdd( 59, 138 );
	l2.SetAttached();

	l3.PolyAdd( 47, 96 ); l3.PolyAdd( 59, 96 );

	l4.PolyAdd( 125, 195 ); l4.PolyAdd( 144, 195 );
	rect.left = 125; rect.right = 144; rect.top = 180; rect.bottom = 194;
	memDC.DrawText( "IR", &rect, DT_CENTER | DT_VCENTER );

	l5.PolyAdd( 92, 128 ); l5.PolyAdd( 108, 128 );

	l6.PolyAdd( 125, 120 ); l6.PolyAdd( 144, 120 );

	l7.PolyAdd( 131, 120 ); l7.PolyAdd( 131, 70 ); l7.PolyAdd( 10, 70 );
	l7.PolyAdd( 10, 165 ); l7.PolyAdd( 20, 165 );
	l7.SetAttached();

	// ID
	l8.PolyAdd( 165, 120 ); l8.PolyAdd( 230, 120 );
	l8.PolyAdd( 230, 90 ); l8.PolyAdd( 270, 90 );

	l9.PolyAdd( 165, 195 ); l9.PolyAdd( 170, 195 );
	l9.PolyAdd( 170, 159 ); l9.PolyAdd( 232, 159 );
	// text "IR6..10"
	rect.left = 170; rect.right = 232; rect.top = 144; rect.bottom = 159;
	memDC.DrawText( "IR6..10", &rect, DT_CENTER | DT_VCENTER );

	l10.PolyAdd( 170, 185 ); l10.PolyAdd( 232, 185 );
	l10.SetAttached();
	// text "IR11..15"
	rect.left = 170; rect.right = 232; rect.top = 170; rect.bottom = 185;
	memDC.DrawText( "IR10..15", &rect, DT_CENTER | DT_VCENTER );

	l11.PolyAdd( 170, 195 ); l11.PolyAdd( 170, 280 ); l11.PolyAdd( 210, 280 );
	l11.SetAttached();
	// text "16"
	rect.left = 200; rect.right = 210; rect.top = 265; rect.bottom = 280;
	memDC.DrawText( "16", &rect, DT_CENTER | DT_VCENTER );

	l12.PolyAdd( 170, 280 ); l12.PolyAdd( 170, 310 ); l12.PolyAdd( 350, 310 );
	l12.SetAttached();

	l13.PolyAdd( 250, 280 ); l13.PolyAdd( 350, 280 );
	// text "32"
	rect.left = 252; rect.right = 270; rect.top = 265; rect.bottom = 280;
	memDC.DrawText( "32", &rect, DT_LEFT | DT_VCENTER );

	l14.PolyAdd( 288, 280 ); l14.PolyAdd( 288, 140 ); l14.PolyAdd( 245, 140 );
	l14.PolyAdd( 245, 50 ); l14.PolyAdd( 270, 50 );
	l14.SetAttached();

	l15.PolyAdd( 284, 220 ); l15.PolyAdd( 350, 220 );

	l16.PolyAdd( 284, 176 ); l16.PolyAdd( 350, 176 );

	l17.PolyAdd( 292, 176 ); l17.PolyAdd( 292, 115 ); l17.PolyAdd( 304, 115 );
	l17.SetAttached();

	l18.PolyAdd( 340, 115 ); l18.PolyAdd( 344, 115 ); l18.PolyAdd( 344, 24 );
	l18.PolyAdd( 116, 24 ); l18.PolyAdd( 116, 100 );
	l18.SetArrow( FALSE );

	l19.PolyAdd( 303, 70 ); l19.PolyAdd( 321, 70 ); l19.PolyAdd( 321, 32 );
	l19.PolyAdd( 97, 32 ); l19.PolyAdd( 97, 110 ); l19.PolyAdd( 108, 110 );

	// EX
	l20.PolyAdd( 371, 176 ); l20.PolyAdd( 430, 176 );

	l21.PolyAdd( 371, 225 ); l21.PolyAdd( 400, 225 );

	l22.PolyAdd( 417, 225 ); l22.PolyAdd( 430, 225 );

	l23.PolyAdd( 380, 225 ); l23.PolyAdd( 380, 250 ); l23.PolyAdd( 480, 250 );
	l23.SetAttached();

	l24.PolyAdd( 371, 280 ); l24.PolyAdd( 390, 280 ); 
	l24.PolyAdd( 390, 235 ); l24.PolyAdd( 400, 235 );

	l25.PolyAdd( 371, 310 ); l25.PolyAdd( 480, 310 );

	l26.PolyAdd( 470, 199 ); l26.PolyAdd( 480, 199 );

	// MEM
	l27.PolyAdd( 501, 199 ); l27.PolyAdd( 540, 199 );

	l28.PolyAdd( 520, 199 ); l28.PolyAdd( 520, 270 ); l28.PolyAdd( 605, 270 );
	l28.SetAttached();

	l29.PolyAdd( 501, 250 ); l29.PolyAdd( 540, 250 );

	l30.PolyAdd( 590, 225 ); l30.PolyAdd( 605, 225 );
	
	l31.PolyAdd( 501, 310 ); l31.PolyAdd( 605, 310 );

	// WB
	l32.PolyAdd( 626, 225 ); l32.PolyAdd( 650, 225 );

	l33.PolyAdd( 626, 270 ); l33.PolyAdd( 638, 270 );
	l33.PolyAdd( 638, 245 ); l33.PolyAdd( 650, 245 );

	l34.PolyAdd( 626, 310 ); l34.PolyAdd( 660, 310 ); l34.PolyAdd( 660, 328 );
	l34.PolyAdd( 175, 328 ); l34.PolyAdd( 175, 211 ); l34.PolyAdd( 232, 211 );
	// text "MEM/WB.IR
	rect.left = 172; rect.right = 232; rect.top = 196, rect.bottom = 211;
	memDC.DrawText( "MEMWB.IR", &rect, DT_LEFT | DT_VCENTER );

	l35.PolyAdd( 668, 235 ); l35.PolyAdd( 680, 235 ); l35.PolyAdd( 680, 336 );
	l35.PolyAdd( 180, 336 ); l35.PolyAdd( 180, 237 ); l35.PolyAdd( 232, 237 );
}

// Call InitLines() prior to this function if first call
void CIntegerDatapathCtrl::DrawAll()
{
//	memDC.FillSolidRect( &rcClient, m_bkColor );
	IFCircuits();
	IFIDRegs();
	IDCircuits();
	IDEXRegs();
	EXCircuits();
	EXMEMRegs();
	MEMCircuits();
	MEMWBRegs();
	WBCircuits();
}

// IF
void CIntegerDatapathCtrl::IFCircuits()
{
	CPen pen;
	pen.CreatePen( m_penStyle, m_penWidth, m_penColor );
	CPen* pOldPen = (CPen*)memDC.SelectObject( &pen );

	CBrush brush, oldBrush;
	brush.CreateSolidBrush( m_bkColor );
	CBrush* pOldBrush = (CBrush*)memDC.SelectObject( brush );
	oldBrush.FromHandle((HBRUSH)pOldBrush);

	CRect rect;

	// PC rectangle
	rect.left = 20; rect.top = 138; rect.right = 40; rect.bottom = 192;
	memDC.Rectangle( &rect );
	// text "PC"
	rect.top = 159; rect.bottom = 171;
	memDC.DrawText( "PC", &rect, DT_CENTER | DT_VCENTER | DT_WORDBREAK );

	// Instruction Memory
	rect.left = 72; rect.top = 155; rect.right = 125; rect.bottom = 220;
	memDC.Rectangle( &rect );
	// text "instruction memory"
	rect.top = 170; rect.bottom = 200;
	memDC.DrawText( "Instr\nmemory", &rect, DT_CENTER | DT_VCENTER );

	// ADD
	CPoint poly[8];
	poly[0] = CPoint( 59, 128 ); poly[1] = CPoint( 59, 147 );
	poly[2] = CPoint( 92, 131 ); poly[3] = CPoint( 92, 104 );
	poly[4] = CPoint( 59, 88 );  poly[5] = CPoint( 59, 107 );
	poly[6] = CPoint( 67, 118 ); poly[7] = CPoint( 59, 128 );
	memDC.Polyline( poly, 8 );
	// text "ADD"
	rect.left = 67; rect.top = 112; rect.right = 95, rect.bottom = 123;
	memDC.DrawText( "ADD", &rect, DT_LEFT | DT_VCENTER );
	// text "4"
	rect.left = 40; rect.right = 47; rect.top = 90; rect.bottom = 102;
	memDC.DrawText( "4", &rect, DT_CENTER | DT_VCENTER );

	// Mux
	rect.left = 108; rect.right = 125; rect.top = 100; rect.bottom = 140;
	memDC.RoundRect( &rect, CPoint(17, 17) );
	// text "Mux"
	memDC.DrawText( "M\nu\nx", &rect, DT_CENTER | DT_VCENTER );

	IFLines( m_penStyle, m_penWidth, m_penColor );

	memDC.SelectObject( &oldBrush );
	memDC.SelectObject( pOldPen );
}

void CIntegerDatapathCtrl::IFLines( int penStyle, int penWidth, COLORREF penColor, CString& str )
{
	m_IFPenStyle = penStyle;
	m_IFPenWidth = penWidth;
	m_IFPenColor = penColor;
	m_IFStr = str;

	l1.Draw( &memDC, penStyle, penWidth, penColor );
	l2.Draw( &memDC, penStyle, penWidth, penColor );
	l3.Draw( &memDC, penStyle, penWidth, penColor );
	l4.Draw( &memDC, penStyle, penWidth, penColor );
	l5.Draw( &memDC, penStyle, penWidth, penColor );
	l6.Draw( &memDC, penStyle, penWidth, penColor );
	l7.Draw( &memDC, penStyle, penWidth, penColor );

	// show current instructions
	CRect rect( 0, 0, 144, 20 );
	COLORREF clr = memDC.SetTextColor( penColor );
	memDC.DrawText( str, &rect, DT_CENTER | DT_VCENTER | DT_WORDBREAK );
	memDC.SetTextColor( clr );
}

void CIntegerDatapathCtrl::RestoreIFLines( BOOL bCore )
{
	IFLines( m_IFPenStyle, m_IFPenWidth, m_bkColor, m_IFStr );
	m_IFStr = _T("");
	if( bCore )	IFLines( m_penStyle, m_penWidth, m_penColor );
}

// IF/ID
void CIntegerDatapathCtrl::IFIDRegs()
{
	CPen pen;
	pen.CreatePen( m_penStyle, m_penWidth, m_penColor );
	CPen* pOldPen = (CPen*)memDC.SelectObject( &pen );

	CBrush brush, oldBrush;
	brush.CreateSolidBrush( m_regColor );
	CBrush* pOldBrush = (CBrush*)memDC.SelectObject( brush );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -