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

📄 cpu.cpp

📁 这个也是我们的毕业设计课题
💻 CPP
字号:
//class CPU implementing
//refer to CPU.h , Relationships between CPU and Instruction
#include "stdafx.h"
#include "DFYSimulator.h"
#include "CPU.H"
#include "MainFrm.h"
#include "OutputWindow.h"
#include "iostream"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#include "IRQDlg.h"
#include "Instruction.h"
#include "BUSSystem.h"
//default construction
CPU::CPU()
{ 
	//General register
	for(int i=0;i<5;i++)
		GR[i]=0;
	//Segment register
	CS=0;
	DS=0;
	ES=0;
	SS=0;
	//Offset register
	IP=0;
	SP=0;
	PC=0;
	//Flags register
	FLAGS=0;
	//Current instruction
	OP=0;//code
	_instruction=NULL;
	_busSystem=NULL;
	m_bBG=FALSE;
	m_bContinue=TRUE;
	m_bIRQ=FALSE;
	m_bIRQMask=0;
	_IRQDlg=NULL;
	for(int j=0;j<MAXNUMBER;j++)
		_instructionEntry[j]=NULL;
}
//destruction
CPU::~CPU()
{
	Instruction *pInstruction;
	for(int j=0;j<MAXNUMBER;j++)
	{
		pInstruction=_instructionEntry[j];
		if(pInstruction)delete pInstruction;
	}
}		
//Initalize
void CPU::Initialize()
{
	//initialize instruction
	LD* pLD=new LD();
	if(!pLD)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	ST* pST=new ST();
	if(!pST)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	LEA* pLEA =new LEA();
	if(!pLEA)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	ADD* pADD=new ADD();
	if(!pADD)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	SUB* pSUB=new SUB();
	if(!pSUB)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	SLA* pSLA=new SLA();
	if(!pSLA)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	SRA* pSRA=new SRA();
	if(!pSRA)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	AND* pAND=new AND();
	if(!pAND)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	OR* pOR=new OR();
	if(!pOR)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	EOR* pEOR=new EOR();
	if(!pEOR)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	NOT* pNOT=new NOT();
	if(!pNOT)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	SLL* pSLL=new SLL();
	if(!pSLL)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	SRL* pSRL=new SRL();
	if(!pSRL)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	CPA* pCPA=new CPA();
	if(!pCPA)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	CPL* pCPL=new CPL();
	if(!pCPL)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	JMP* pJMP=new JMP();
	if(!pJMP)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	JPZ* pJPZ=new JPZ();
	if(!pJPZ)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	JMI* pJMI=new JMI();
	if(!pJMI)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	JNZ* pJNZ=new JNZ();
	if(!pJNZ)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	JZE* pJZE=new JZE();
	if(!pJZE)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	PUSH* pPUSH=new PUSH();
	if(!pPUSH)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	POP* pPOP=new POP();
	if(!pPOP)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	CALL* pCALL=new CALL();
	if(!pCALL)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	RET* pRET=new RET();
	if(!pRET)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	INPORT* pINPORT=new INPORT();
	if(!pINPORT)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	OUTPORT* pOUTPORT=new OUTPORT();
	if(!pOUTPORT)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	EXIT* pEXIT=new EXIT();
	if(!pEXIT)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	CLI* pCLI=new CLI();
	if(!pCLI)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	STI* pSTI=new STI();
	if(!pSTI)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	IRET* pIRET=new IRET();
	if(!pIRET)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	INTR* pINTR=new INTR();
	if(!pINTR)
	{
		MessageBox(NULL,"not enough memory !","Fatal error !",MB_OK);
		return;
	}
	//load instruction
	AddInstruction(pLD,pLD->GetinstructionCode());
	AddInstruction(pST,pST->GetinstructionCode());
	AddInstruction(pLEA,pLEA->GetinstructionCode());
	AddInstruction(pADD,pADD->GetinstructionCode());
	AddInstruction(pSUB,pSUB->GetinstructionCode());
	AddInstruction(pSLA,pSLA->GetinstructionCode());
	AddInstruction(pSRA,pSRA->GetinstructionCode());
	AddInstruction(pAND,pAND->GetinstructionCode());
	AddInstruction(pOR,pOR->GetinstructionCode());
	AddInstruction(pEOR,pEOR->GetinstructionCode());
	AddInstruction(pNOT,pNOT->GetinstructionCode());
	AddInstruction(pSLL,pSLL->GetinstructionCode());
	AddInstruction(pSRL,pSRL->GetinstructionCode());
	AddInstruction(pCPA,pCPA->GetinstructionCode());
	AddInstruction(pCPL,pCPL->GetinstructionCode());
	AddInstruction(pJMP,pJMP->GetinstructionCode());
	AddInstruction(pJPZ,pJPZ->GetinstructionCode());
	AddInstruction(pJMI,pJMI->GetinstructionCode());
	AddInstruction(pJNZ,pJNZ->GetinstructionCode());
	AddInstruction(pJZE,pJZE->GetinstructionCode());
	AddInstruction(pPUSH,pPUSH->GetinstructionCode());
	AddInstruction(pPOP,pPOP->GetinstructionCode());
	AddInstruction(pCALL,pCALL->GetinstructionCode());
	AddInstruction(pRET,pRET->GetinstructionCode());
	AddInstruction(pINPORT,pINPORT->GetinstructionCode());
	AddInstruction(pOUTPORT,pOUTPORT->GetinstructionCode());
	AddInstruction(pEXIT,pEXIT->GetinstructionCode());
	AddInstruction(pCLI,pCLI->GetinstructionCode());
	AddInstruction(pSTI,pSTI->GetinstructionCode());
	AddInstruction(pIRET,pIRET->GetinstructionCode());
	AddInstruction(pINTR,pINTR->GetinstructionCode());
}
//attribute
void CPU::SetGR(WORD wGR,BYTE bIndex)
{
	if(bIndex<0||bIndex>4)
	{
		ReportState("Sorry,the register you want acess is not exist");
		return;
	}
	GR[bIndex]=wGR;
}
WORD CPU::GetGR(BYTE bIndex)
{
	if(bIndex<0||bIndex>4)
	{
		ReportState("Sorry,the register you want acess is not exist");
		return 0;
	}
	return GR[bIndex];
}

//specify Instruction for each Instruction code 
int CPU::AddInstruction(Instruction* lpInstruction,BYTE bCode)
{
	if(bCode<0)
	{
		ReportState("sorry ,the Instruction code\ncan't below 0 ");	
		return 0;
	}
	_instructionEntry[bCode]=lpInstruction;
	lpInstruction->SetCPU(this);
	return bCode;
}
Instruction* CPU::GetInstruction(BYTE bIndex)
{
	if(bIndex<0||bIndex>127)
	{
		ReportState("Sorry,the instruction you\n want is not exist,the value of bIndex is illegal");
		return NULL;
	}
	else
		return _instructionEntry[bIndex];
}
//BUS operation
UNSHORT CPU::ReadAddrFromAddrBUS()
{
	if(!m_bBG)//if the CPU not occupying the BUS
	{
		ReportState("Sorry! You can't use this operation,because you haven't get the BUS control. Please call the function RequstBUS() first");
		return 0;
	}
	UNSHORT uAddr;
	if(_busSystem)
	{
		_busSystem->ReadAddrFromAddrBUS(uAddr);
		return uAddr;
	}
	else
	{
		ReportState("Sorry! CPU can't find BUSSystem,Attach it to a BUSSystem and try again");
		return 0;
	}
}
void CPU::WriteAddrToAddrBUS(UNSHORT uAddr)
{
	if(!m_bBG)//if the CPU not occupying the BUS
	{
		ReportState("Sorry! You can't use this operation,because you haven't get the BUS control. Please call the function RequstBUS() first");
		return;
	}
	if(_busSystem)
	{
		_busSystem->WriteAddrToAddrBUS(uAddr);
		return;
	}
	else
	{
		ReportState("Sorry , CPU can't find BUSSystem,Attach it to a BUSSystem and try again");
		return;
	}
}
void CPU::SetIORead(BOOL bState)
{
	if(!m_bBG)//if the CPU not occupying the BUS
	{
		ReportState("Sorry! You can't use this operation,because you haven't get the \n\
						BUS control. Please call the \n\
						function RequstBUS() first");
		return;
	}
	if(_busSystem)
	{
		_busSystem->SetIORead(bState);
		return;
	}
	else
	{
		ReportState("Sorry , CPU can't find BUSSystem,\n\
						Attach it to a BUSSystem and \n\
						try again");
		return ;
	}
}
void CPU::SetIOWrite(BOOL bState)
{
	if(!m_bBG)//if the CPU not occupying the BUS
	{
		ReportState("Sorry! You can't use this operation,\n\
						because you haven't get the \n\
						BUS control. Please call the \n\
						function RequstBUS() first");
		return;
	}
	if(_busSystem)
	{
		_busSystem->SetIOWrite(bState);
		return;
	}
	else
	{
		ReportState("Sorry , CPU can't find BUSSystem,\n\
						Attach it to a BUSSystem and \n\
						try again");
		return ;
	}
}
WORD CPU::ReadDataFromMemory()
{
	if(!m_bBG)//if the CPU not occupy the BUS
	{
		ReportState("Sorry! You can't use this operation,\n\
						because you haven't get the \n\
						BUS control. Please call the \n\
						function RequstBUS() first");
		return 0;
	}
	WORD wData;
	if(_busSystem)
	{
		SetIORead(FALSE);//set the IO state to Read
		_busSystem->AccessMemory();//read data from memory and
										//put it into the DataBUS
		_busSystem->ReadDataFromDataBUS(wData);
		SetIORead(TRUE);//reset the IO Read state
		return wData;
	}

	else
	{
		ReportState("Sorry , CPU can't find BUSSystem,\n\
						Attach it to a BUSSystem and \n\
						try again");
		return 0;
	}
}
void CPU::WriteDataToMemory(WORD& wData)
{
	if(!m_bBG)//if the CPU not occupying the BUS
	{
		ReportState("Sorry! You can't use this operation,\n\
						because you haven't get the \n\
						BUS control. Please call the \n\
						function RequstBUS() first");
		return;
	}
	if(_busSystem)
	{
		SetIOWrite(FALSE);//set the Write state
		_busSystem->WriteDataToDataBUS(wData);
		_busSystem->AccessMemory();
		SetIOWrite(TRUE);//reset the Write state

		return;
	}
	else
	{
		ReportState("Sorry , CPU can't find BUSSystem,\n\
						Attach it to a BUSSystem and \n\
						try again");
		return;
	}
}
void CPU::RequestBUS()
{
	if(_busSystem)
	{
		while(!(m_bBG=_busSystem->Determine()));
		return; 
	}
	else
	{
		ReportState("Sorry , CPU can't find BUSSystem,Attach it to a BUSSystem and try again!");
		return;
	}
}
void CPU::ReleaseBUS()
{
	if(_busSystem)
	{
		m_bBG=FALSE;
		_busSystem->SetBS(FALSE);
	}
	else
	{
		ReportState("Sorry , CPU can't find BUSSystem,Attach it to a BUSSystem and try again");
		return;
	}
}

//operation
 void CPU::LoadInstructionFromMemory()//load a instruction from memory
 {
 	DWORD dwOP;//will hold the operation code
 	WORD wData=0;
 	UNSHORT uAddr=PC;
 	RequestBUS();
 	WriteAddrToAddrBUS(uAddr);
 	wData=ReadDataFromMemory();
	ReleaseBUS();
 	dwOP=(DWORD)wData;
 	OP=dwOP<<16;
	RequestBUS();
 	uAddr+=1;
	WriteAddrToAddrBUS(uAddr);
 	wData=ReadDataFromMemory();
 	ReleaseBUS();
	dwOP=DWORD(wData);
 	OP+=dwOP;
 }
void CPU::Excute()
{
	if((GetFLAGS()&0X0008))//if set the IF flag
	{
		if(_IRQDlg)
		{
			m_bIRQ=_IRQDlg->GetIRQState();
			if(m_bIRQ)//if have Interrupt Request
			{
				Ack();//ack
				_IRQDlg->Determine();
				UINT uIRQNum=_IRQDlg->GetCurIRQNum();
				if(uIRQNum<=8)//if the uIRQNum is legal
				{
					CString str1;
					str1.Format("handle IRQ%d interrupt...",uIRQNum);
					_IRQDlg->ReportHandleState(str1);
					CString str2;
					str2.Format("IRQ%d",uIRQNum);
					_IRQDlg->DeleteStr(str2);
					BYTE bReqBit=_IRQDlg->GetReqBit();
					BYTE bMask=~(0X01<<(uIRQNum-1));
					bReqBit&=bMask;
					_IRQDlg->SetReqBit(bReqBit);
					str1.Format("handle IRQ%d succeed",uIRQNum);
					_IRQDlg->ReportHandleState(str1);
					return;
				}
			}
		}
	}//end: set the TF flag
	if((GetFLAGS() & 0X0010))//if set TF flag ,will cause the step interrupt
	{
		if(m_bContinue)
		{
			LoadInstructionFromMemory();
			BYTE bCode1=BYTE(OP>>25);
			_instruction=GetInstruction(bCode1);
			_instruction->Excute(OP);//excute the Code
			m_bContinue=FALSE;
		}
		else
		{
			//idle
			//do nothing until the user set the m_bContinue 
			//state to TRUE
		}
	}
	else
	{
		LoadInstructionFromMemory();
		BYTE bCode2=BYTE(OP>>25);//specify the Instruction code
		_instruction=GetInstruction(bCode2);
		if(_instruction)
		{
			_instruction->Excute(OP);
		}
		else
		{
			ReportState("Sorry, no appropriate instruction handle\n this operation code");
		}
	}

}
//feature that will use in future
int CPU::AddRegister(LPCTSTR lpRegisterName)
{
	return 0;
}


void CPU::ReportState(CString strState)
{
	CMainFrame* pMainFrame=(CMainFrame*)AfxGetMainWnd();
	COutputWindow* pOutputWindow=pMainFrame->GetOutputWindow();
	if(pOutputWindow)
	{
		pOutputWindow->ShowState(strState);
	}

}

void CPU::Ack()
{
	if(_IRQDlg)
		_IRQDlg->ReportHandleState("_cpu ACK...");
}

void CPU::SetIRQMask(BYTE bMask)
{
	m_bIRQMask=bMask;
}

BYTE CPU::GetIRQMask()
{
	return m_bIRQMask;
}

void CPU::SetIntCtrl(CIRQDlg *pIRQDlg)
{
	_IRQDlg=pIRQDlg;
}

⌨️ 快捷键说明

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