📄 simplecpudlg.cpp
字号:
// SimpleCPUDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "SimpleCPU.h"
#include "SimpleCPUDlg.h"
#include ".\SimpleCPUdlg.h"
#include "EditDlg.h"
#include "SetDlg.h"
#include<stdlib.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
enum {PC,AR,ABUS,MEMORY,DBUS,DR,IR,TRAN,CONTROL,ALU,ACC};
// CSimpleCPUDlg 对话框
CSimpleCPUDlg::CSimpleCPUDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSimpleCPUDlg::IDD, pParent)
, IntPC(0)
, IntAR(0)
, IntACC(0)
, pLastStat(NULL)
{
SubStep=0;
ProStart=false;
InsStart=false;
pauseflag=false;
Mode=1;
TimeDis=1000;
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_Brush.CreateSolidBrush(RGB(255,255,255));
m_Bitmap.LoadBitmap(IDC_CPUBIT);
}
void CSimpleCPUDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDE_PC, StatPC);
DDX_Control(pDX, IDE_AR, StatAR);
DDX_Control(pDX, IDE_DR, StatDR);
DDX_Control(pDX, IDE_IR, StatIR);
DDX_Control(pDX, IDE_TRANSLATE, StatTranslate);
DDX_Control(pDX, IDE_CONTROL, StatControl);
DDX_Control(pDX, IDE_ALU, StatALU);
DDX_Control(pDX, IDE_ACC, StatACC);
DDX_Control(pDX, IDC_MEMORY, MemoryCtrl);
DDX_Control(pDX, IDE_ABUS, StatABUS);
DDX_Control(pDX, IDE_DBUS, StatDBUS);
}
BEGIN_MESSAGE_MAP(CSimpleCPUDlg, CDialog)
ON_WM_SYSCOMMAND()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_NEXTSTEP, OnBnClickedNextstep)
ON_WM_CTLCOLOR()
ON_WM_ERASEBKGND()
ON_WM_TIMER()
ON_BN_CLICKED(IDC_EDITCODE, OnBnClickedEditcode)
ON_BN_CLICKED(IDC_SET, OnBnClickedSet)
ON_BN_CLICKED(IDC_START, OnBnClickedStart)
ON_BN_CLICKED(IDC_PAUSE, OnBnClickedPause)
ON_BN_CLICKED(IDC_IMFOR, OnBnClickedImfor)
END_MESSAGE_MAP()
// CSimpleCPUDlg 消息处理程序
const OPERFN CSimpleCPUDlg::SubStep1[]={
ComPC,
ComAR,
ComABUS,
ComMemory,
ComDBUS,
ComDR,
ComIR,
ComTran,
ComControl,
ComALU,
ComACC
};
BOOL CSimpleCPUDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 将\“关于...\”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
MemoryCtrl.SetExtendedStyle(LVS_EX_GRIDLINES|LVS_EX_FULLROWSELECT);
LV_COLUMN lv;
lv.mask=LVCF_TEXT|LVCF_FMT|LVCF_WIDTH;
lv.pszText="地址";
lv.fmt=LVCFMT_LEFT;
lv.cx=50;
MemoryCtrl.InsertColumn(0,&lv);
lv.pszText="代码";
lv.cx=120;
MemoryCtrl.InsertColumn(1,&lv);
MemoryCtrl.SetBkColor(RGB(255,255,255));
HBITMAP hbmp;
for(int i=0;i<6;i++)
{
m_button[i].LoadBitmap(IDB_BITMAP1+i);
hbmp=(HBITMAP)m_button[i].GetSafeHandle();
((CButton*)GetDlgItem(IDC_NEXTSTEP+i))->SetBitmap(hbmp);
}
return TRUE; // 除非设置了控件的焦点,否则返回 TRUE
}
void CSimpleCPUDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
CDialog::OnSysCommand(nID, lParam);
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CSimpleCPUDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标显示。
HCURSOR CSimpleCPUDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CSimpleCPUDlg::OnBnClickedNextstep()
{
//(this->*fn[0])();
if(!ProStart)
{
AfxMessageBox("程序已经运行完,请按“运行”重新运行");
return;
}
if(InstructList.size()==0)
{
AfxMessageBox("没有程序导入,请先按“编辑代码”按钮编辑导入代码");
ProStart=false;
return;
}
if(pauseflag)OnBnClickedPause();
SetTimer(1,TimeDis,0);
InsStart=true;
}
void CSimpleCPUDlg::OnBnClickedEditcode()
{
CEditDlg dlg(InstructList);
if(dlg.DoModal()==IDOK)
{
InstructList=dlg.InstructList;
LoadMemory();
ReLoad();
ProStart=false;
}
}
HBRUSH CSimpleCPUDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if(nCtlColor==CTLCOLOR_STATIC)
{
pDC->SetBkColor(RGB(255,255,255));
return (HBRUSH)m_Brush;
}
return hbr;
}
BOOL CSimpleCPUDlg::OnEraseBkgnd(CDC* pDC)
{
if (m_Bitmap.m_hObject!=NULL) // 对象句柄非空
{
CDC MemDC;
BITMAP bm;
CRect Rect;
int x=0, y=0;
GetClientRect (&Rect); // 获取客户区大小
m_Bitmap.GetObject (sizeof (BITMAP),&bm); // 用位图上的信息 填充 BITMAP 结构的各个域
MemDC.CreateCompatibleDC (pDC); // 初始化内存描述对象
CBitmap*pOldBitmap=MemDC.SelectObject (&m_Bitmap); // 定 义一个 CBITMAP 类,并初始化为选入到设备描述对象的位图
pDC->BitBlt(x,y,bm.bmWidth,bm.bmHeight,&MemDC,0,0,SRCCOPY);
MemDC.SelectObject ( pOldBitmap ); // 将位图对象选入
return TRUE;
}
else return CDialog::OnEraseBkgnd (pDC);
}
void CSimpleCPUDlg::OnTimer(UINT nIDEvent)
{
(this->*SubStep1[SubStep])();
if(Mode==0 || Mode==1&&!InsStart|| !ProStart)
KillTimer(1);
CDialog::OnTimer(nIDEvent);
}
void CSimpleCPUDlg::LoadMemory(void)
{
MemoryCtrl.DeleteAllItems();
int length=InstructList.size();
CString ins;
char num[20];
for(int index=0;index<length;index++)
{
itoa(index,num,10);
MemoryCtrl.InsertItem(index,num);
ins=InstructList[index].instruct;
MemoryCtrl.SetItemText(index,1,ins);
}
}
void CSimpleCPUDlg::SetLastHide(void)
{
if(pLastStat)
{
pLastStat->Show(false);
pLastStat->Invalidate();
}
}
void CSimpleCPUDlg::ComPC(void)
{
char num[20];
SetLastHide();
if(pLastStat==&StatAR)
{
IntPC++;
SubStep=ABUS;
}
else if(pLastStat==&StatIR)
{
IntPC=InstructList[IntAR].data;
SubStep=PC;
InsStart=false;
}
else
SubStep=AR;
itoa(IntPC,num,10);
StatPC.Show();
StatPC.SetWindowText(num);
pLastStat=&StatPC;
}
void CSimpleCPUDlg::ComAR(void)
{
char num[20];
SetLastHide();
if(pLastStat==&StatPC)
{
IntAR=IntPC;
SubStep=PC;
}
else if(pLastStat==&StatIR)
{
IntAR=InstructList[IntAR].data;
SubStep=ABUS;
}
itoa(IntAR,num,10);
StatAR.Show();
StatAR.SetWindowText(num);
pLastStat=&StatAR;
}
void CSimpleCPUDlg::ComABUS(void)
{
SetLastHide();
StatABUS.Show();
StatABUS.Invalidate();
SubStep=MEMORY;
pLastStat=&StatABUS;
}
void CSimpleCPUDlg::ComMemory(void)
{
char num[20];
CString instruct="DB ";
SetLastHide();
MemoryCtrl.SetFocus();
MemoryCtrl.SetItemState(-1,0,LVIS_SELECTED);
MemoryCtrl.SetItemState(IntAR,LVIS_SELECTED,LVIS_SELECTED );
MemoryCtrl.EnsureVisible(IntAR,FALSE);
if(pLastStat==&StatDBUS)
{
InstructList[IntAR].data=IntACC;
itoa(IntACC,num,10);
instruct+=num;
InstructList[IntAR].instruct=instruct;
MemoryCtrl.SetItemText(IntAR,1,instruct);
SubStep=PC;
InsStart=false;
}
else if(pLastStat==&StatABUS)
{
if(InstructList[IntAR].oper==DB
&&InstructList[IntPC-1].oper==STA)
SubStep=ACC;
else SubStep=DBUS;
}
pLastStat=NULL;
}
void CSimpleCPUDlg::ComDBUS(void)
{
SetLastHide();
StatDBUS.Show();
StatDBUS.Invalidate();
if(pLastStat==&StatDR)SubStep=MEMORY;
else SubStep=DR;
pLastStat=&StatDBUS;
}
void CSimpleCPUDlg::ComDR(void)
{
SetLastHide();
StatDR.Show();
char num[20];
if(pLastStat==&StatDBUS)
{
if(InstructList[IntAR].oper==DB)
SubStep=ALU;
else SubStep=IR;
CString str=InstructList[IntAR].instruct;
StatDR.SetWindowText(str);
}
else
{
SubStep=DBUS;
itoa(IntACC,num,10);
StatDR.SetWindowText(num);
}
pLastStat=&StatDR;
}
void CSimpleCPUDlg::ComIR(void)
{
SetLastHide();
StatIR.Show();
if(pLastStat==&StatDR)
{
SubStep=TRAN;
CString str=InstructList[IntAR].instruct;
StatIR.SetWindowText(str);
}
else
{
if(InstructList[IntAR].oper==JMP)
SubStep=PC;
else SubStep=AR;
StatIR.Invalidate();
}
pLastStat=&StatIR;
}
void CSimpleCPUDlg::ComTran(void)
{
SetLastHide();
StatTranslate.Show();
StatTranslate.Invalidate();
SubStep=CONTROL;
pLastStat=&StatTranslate;
}
void CSimpleCPUDlg::ComControl(void)
{
Instruction InsCode=InstructList[IntAR];
if(InsCode.addr||InsCode.oper==JMP)
SubStep=IR;
else SubStep=ALU;
SetLastHide();
StatControl.Show();
StatControl.Invalidate();
pLastStat=&StatControl;
}
void CSimpleCPUDlg::ComALU(void)
{
Instruction InsCode=InstructList[IntPC-1];
SubStep=ACC;
switch(InsCode.oper)
{
case ADD:
if(InsCode.addr)
IntACC+=InstructList[IntAR].data;
else IntACC+=InsCode.data;
break;
case SUB:
if(InsCode.addr)
IntACC-=InstructList[IntAR].data;
else IntACC-=InsCode.data;
break;
case MUL:
if(InsCode.addr)
IntACC*=InstructList[IntAR].data;
else IntACC*=InsCode.data;
break;
case DIV:
if(InsCode.addr)
IntACC/=InstructList[IntAR].data;
else IntACC/=InsCode.data;
break;
case LOD:
IntACC=InstructList[IntAR].data;
break;
case HALT:
ProStart=false;
SubStep=PC;
break;
case NOP:
InsStart=false;
SubStep=PC;
break;
}
SetLastHide();
StatALU.Show();
StatALU.Invalidate();
pLastStat=&StatALU;
}
void CSimpleCPUDlg::ComACC(void)
{
char num[20];
itoa(IntACC,num,10);
SetLastHide();
StatACC.Show();
StatACC.SetWindowText(num);
if(!pLastStat)
{
SubStep=DR;
}
else
{
SubStep=PC;
InsStart=false;
}
pLastStat=&StatACC;
}
void CSimpleCPUDlg::OnBnClickedSet()
{
OnBnClickedPause();
CSetDlg dlg(Mode,TimeDis);
dlg.DoModal();
}
void CSimpleCPUDlg::ReLoad(void)
{
IntPC=0;
IntAR=0;
IntACC=0;
StatPC.SetWindowText("PC");
StatAR.SetWindowText("AR");
StatDR.SetWindowText("DR");
StatIR.SetWindowText("IR");
StatACC.SetWindowText("ACC");
}
void CSimpleCPUDlg::OnBnClickedStart()
{
ReLoad();
ProStart=true;
OnBnClickedNextstep();
}
void CSimpleCPUDlg::OnBnClickedPause()
{
if(!ProStart)return;
m_button[5].DeleteObject();
if(!pauseflag)
{
KillTimer(1);
m_button[5].LoadBitmap(IDB_BITMAP7);
pauseflag=true;
}
else
{
SetTimer(1,TimeDis,0);
m_button[5].LoadBitmap(IDB_BITMAP6);
pauseflag=false;
}
HBITMAP hbmp=(HBITMAP)m_button[5].GetSafeHandle();
((CButton*)GetDlgItem(IDC_PAUSE))->SetBitmap(hbmp);
}
void CSimpleCPUDlg::OnBnClickedImfor()
{
ShellExecute(0,NULL,"设计报告.chm", NULL,NULL, SW_NORMAL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -