📄 instruction.cpp
字号:
//class Instruction imlementing
//refer to Instruction.h , Relationships between Instruction
//and CPU
#include "stdafx.h"
#include "DFYSimulator.h"
#include "Instruction.h"
#include "MainFrm.h"
#include "OutputWindow.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#include "CPU.h"
//construction/destruction
Instruction::Instruction()
{
_cpu=NULL;
m_bInstructionCode=0;
m_strName="default";
}
Instruction::~Instruction()
{
_cpu=NULL;
m_bInstructionCode=0;
}
//attribute
void Instruction::SetCPU(CPU* lpCPU)
{
_cpu=lpCPU;
}
void Instruction::SetinstructionCode(BYTE& bCode)
{
m_bInstructionCode=bCode;
m_strName="defualt";
}
BYTE Instruction::GetinstructionCode()
{
return m_bInstructionCode;
}
CPU* Instruction::GetCPU()
{
if(_cpu)
return _cpu;
else
{
ReportState("this instruction have't attach to _cpu");
return NULL;
}
}
//operation
void Instruction::Excute(DWORD dwCode)
{
ReportState("this instruction do nothing");
return;
}
void LD::Excute(DWORD dwCode)
{
WORD uIP=_cpu->GetIP();
DWORD dw=dwCode & 0x01C00000;//specify the operand numbers
if(dw==0x00800000)//2 operand (LD GR,ADR),GR<-(ADR)
{
DWORD dwTemp1;
dwTemp1=dwCode & 0x0000FFFF;//get the memory address,
//the address is stored in the 15-0 bit of dwCode
UNSHORT uAddr=UNSHORT(dwTemp1+uIP);//convert the address into 16 bits format
WORD wData1=0;
_cpu->RequestBUS();
_cpu->WriteAddrToAddrBUS(uAddr);
wData1=_cpu->ReadDataFromMemory();
_cpu->ReleaseBUS();
_cpu->SetTempData(wData1);
BYTE bIndex=BYTE((dwCode & 0x00070000)>>16);//specify the register index
//the index of register is stored in 18-16 bit of dwCode
_cpu->SetGR(wData1,bIndex);
}
else if(dw==0x00C00000)//3 operand (LD GRd,imm,GRd),GRd<-(imm+(GRs))
{
DWORD dwTemp2;
dwTemp2=dwCode & 0x0000FFFF;//get immediate data,
//the data is stores in the 15-0 bit of dwCode
WORD wData2=WORD(dwTemp2+uIP);//
BYTE bIndexSrc=BYTE((dwCode & 0x00070000)>>16);//specify the source register index
//the index of source register is stored in 18-16 bit of dwCode
BYTE bIndexDst=BYTE((dwCode & 0x00380000)>>19);//specify the destination register
//the index of source register is stored in 21-19 bit of dwCode
UNSHORT uAddr2=UNSHORT(wData2+(_cpu->GetGR(bIndexSrc)));
_cpu->RequestBUS();
_cpu->WriteAddrToAddrBUS(uAddr2);
wData2=_cpu->ReadDataFromMemory();
_cpu->ReleaseBUS();
_cpu->SetGR(wData2,bIndexDst);
}
else
{
ReportState("the 'LD' instruction can't handle this code");
return;
}
UNSHORT uAddr=_cpu->GetPC();
_cpu->SetPC(uAddr+2);
}
void ST::Excute(DWORD dwCode)
{
WORD uIP=_cpu->GetIP();
DWORD dw=dwCode & 0X01C00000;//specify the operand number
if(dw==0X00800000)//2 operand (ST GR,ADR),GR->(ADR)
{
BYTE bIndex=BYTE((dwCode & 0X00070000)>>16);//specofy the register index
//the index of register is stored in 18-16 bit of dwCode
WORD wData1=_cpu->GetGR(bIndex);//read the data holdes in the register
DWORD dwTemp1=dwCode & 0X0000FFFF;//get the memory address
UNSHORT uAddr1=UNSHORT(dwTemp1+uIP);//convert the address into 16 bits formats
_cpu->RequestBUS();
_cpu->WriteAddrToAddrBUS(uAddr1);
_cpu->WriteDataToMemory(wData1);//write the data which read from the register to memory
_cpu->ReleaseBUS();
}
else if(dw==0X00C00000)//3 operand (ST GRd,imm,GRs),GRd->(imm+(GRs))
{
DWORD dwTemp2=dwCode & 0X0000FFFF;//get the immediate data
//the immediate data is holdes in the 15-0 bit of dwCode
BYTE bIndexSrc=BYTE((dwCode & 0X00070000)>>16);//secify the source register
//the register index is stored in the 18-16 bit of dwCode
BYTE bIndexDst=BYTE((dwCode & 0X00380000)>>19);//secify the destination register
//the register index is stored in the 21-19 bit of dwCode
WORD wData2=WORD(dwTemp2);
UNSHORT uAddr2=UNSHORT(wData2+_cpu->GetGR(bIndexSrc));
wData2=_cpu->GetGR(bIndexDst);//get the data in the destination register
_cpu->RequestBUS();
_cpu->WriteAddrToAddrBUS(uAddr2+uIP);
_cpu->WriteDataToMemory(wData2);
_cpu->ReleaseBUS();
}
else
{
ReportState("the 'ST' instruction can't handle this code");
return;
}
UNSHORT uAddr=_cpu->GetPC();
_cpu->SetPC(uAddr+2);
}
void LEA::Excute(DWORD dwCode)
{
WORD uIP=_cpu->GetIP();
DWORD dw=dwCode & 0X01C00000;//specify the operand mumber
WORD wFlags=_cpu->GetFLAGS();//flag register
if(dw==0x00800000)//2 operand (LEA GR,ADR),GR<-ADR
{
DWORD dwTemp1=dwCode & 0X0000FFFF;//get the immediate data
WORD wData1=WORD(dwTemp1+uIP);//convert it into 16 bits format
BYTE bIndex=BYTE((dwCode & 0X00070000)>>16);//specify the register index
//the index is stored in the 18-16 bit of dwCode
_cpu->SetGR(wData1,bIndex);
//change the flags register
if(wData1>0)
{
wFlags &=0XFFFC;
_cpu->SetFLAGS(wFlags);
}
else if(wData1=0)
{
wFlags &=0XFFFC;
wFlags |=0X0001;
_cpu->SetFLAGS(wFlags);
}
else if(wData1<0)
{
wFlags &=0XFFFC;
wFlags |=0X0002;
_cpu->SetFLAGS(wFlags);
}
}
else if(dw==0X00C00000)//3 operand (LEA GRd,imm,GRs),GRd<-imm+(GRs)
{
DWORD dwTemp2=dwCode & 0X0000FFFF;
WORD wData2=WORD(dwTemp2+uIP);
BYTE bIndexSrc=BYTE((dwCode & 0X00070000)>>16);
BYTE bIndexDst=BYTE((dwCode & 0X00380000)>>19);
wData2+=_cpu->GetGR(bIndexSrc);
_cpu->SetGR(wData2,bIndexDst);
//change the flags
if(wData2>0)
{
wFlags &=0XFFFC;
_cpu->SetFLAGS(wFlags);
}
else if(wData2=0)
{
wFlags &=0XFFFC;
wFlags |=0X0001;
_cpu->SetFLAGS(wFlags);
}
else if(wData2<0)
{
wFlags &=0XFFFC;
wFlags |=0X0002;
_cpu->SetFLAGS(wFlags);
}
}
else
{
ReportState("the 'LEA' instruction can't handle this code");
return;
}
UNSHORT uAddr=_cpu->GetPC();
_cpu->SetPC(uAddr+2);
}
void ADD::Excute(DWORD dwCode)
{
WORD uIP=_cpu->GetIP();
DWORD dw=dwCode & 0X01C00000;//specify operand number
WORD wFlags=_cpu->GetFLAGS();//flag register
if(dw==0x00800000)//2 operand (ADD GR,ADR),GR<-(GR)+(ADR)
{
DWORD dwTemp1=dwCode & 0X0000FFFF;//get the immediate data
UNSHORT uAddr1=UNSHORT(dwTemp1+uIP);
_cpu->RequestBUS();
_cpu->WriteAddrToAddrBUS(uAddr1);
WORD wData1=_cpu->ReadDataFromMemory();
_cpu->ReleaseBUS();
//register operation
BYTE bIndex=BYTE((dwCode & 0X00070000)>>16);
wData1+=_cpu->GetGR(bIndex);
_cpu->SetGR(wData1,bIndex);
//change the flags register
if(wData1>0)
{
wFlags &=0XFFFC;
_cpu->SetFLAGS(wFlags);
}
else if(wData1=0)
{
wFlags &=0XFFFC;
wFlags |=0X0001;
_cpu->SetFLAGS(wFlags);
}
else if(wData1<0)
{
wFlags &=0XFFFC;
wFlags |=0X0002;
_cpu->SetFLAGS(wFlags);
}
}
else if(dw==0X00C00000)//3 operand (ADD GRd,imm,GRs),GRd<-(GRd)+(imm+(GRs))
{
DWORD dwTemp2=dwCode & 0X0000FFFF;
WORD wData2=WORD(dwTemp2+uIP);
BYTE bIndexSrc=BYTE((dwCode & 0X00070000)>>16);
BYTE bIndexDst=BYTE((dwCode & 0X00380000)>>19);
UNSHORT uAddr2=UNSHORT(wData2+_cpu->GetGR(bIndexSrc));
_cpu->RequestBUS();
_cpu->WriteAddrToAddrBUS(uAddr2);
wData2=_cpu->ReadDataFromMemory();
_cpu->ReleaseBUS();
wData2+=_cpu->GetGR(bIndexDst);
_cpu->SetGR(wData2,bIndexDst);
//change the flags
if(wData2>0)
{
wFlags &=0XFFFC;
_cpu->SetFLAGS(wFlags);
}
else if(wData2=0)
{
wFlags &=0XFFFC;
wFlags |=0X0001;
_cpu->SetFLAGS(wFlags);
}
else if(wData2<0)
{
wFlags &=0XFFFC;
wFlags |=0X0002;
_cpu->SetFLAGS(wFlags);
}
}
else
{
ReportState("the 'ADD' instruction can't handle this code");
return;
}
UNSHORT uAddr=_cpu->GetPC();
_cpu->SetPC(uAddr+2);
}
void SUB::Excute(DWORD dwCode)
{
WORD uIP=_cpu->GetIP();
DWORD dw=dwCode & 0X01C00000;//specify operand number
WORD wFlags=_cpu->GetFLAGS();//flag register
if(dw==0x00800000)//2 operand (SUB GR,ADR),GR<-(GR)-(ADR)
{
DWORD dwTemp1=dwCode & 0X0000FFFF;//get the immediate data
UNSHORT uAddr1=UNSHORT(dwTemp1+uIP);
_cpu->RequestBUS();
_cpu->WriteAddrToAddrBUS(uAddr1);
WORD wData1=_cpu->ReadDataFromMemory();
_cpu->ReleaseBUS();
//register operation
BYTE bIndex=BYTE((dwCode & 0X00070000)>>16);
wData1=_cpu->GetGR(bIndex)-wData1;
_cpu->SetGR(wData1,bIndex);
//change the flags register
if(wData1>0)
{
wFlags &=0XFFFC;
_cpu->SetFLAGS(wFlags);
}
else if(wData1=0)
{
wFlags &=0XFFFC;
wFlags |=0X0001;
_cpu->SetFLAGS(wFlags);
}
else if(wData1<0)
{
wFlags &=0XFFFC;
wFlags |=0X0002;
_cpu->SetFLAGS(wFlags);
}
}
else if(dw==0X00C00000)//3 operand (SUB GRd,imm,GRs),GRd<-(GRd)-(imm+(GRs))
{
DWORD dwTemp2=dwCode & 0X0000FFFF;
WORD wData2=WORD(dwTemp2+uIP);
BYTE bIndexSrc=BYTE((dwCode & 0X00070000)>>16);
BYTE bIndexDst=BYTE((dwCode & 0X00380000)>>19);
UNSHORT uAddr2=UNSHORT(wData2+_cpu->GetGR(bIndexSrc));
_cpu->RequestBUS();
_cpu->WriteAddrToAddrBUS(uAddr2);
wData2=_cpu->ReadDataFromMemory();
_cpu->ReleaseBUS();
wData2=_cpu->GetGR(bIndexDst)-wData2;
_cpu->SetGR(wData2,bIndexDst);
//change the flags
if(wData2>0)
{
wFlags &=0XFFFC;
_cpu->SetFLAGS(wFlags);
}
else if(wData2=0)
{
wFlags &=0XFFFC;
wFlags |=0X0001;
_cpu->SetFLAGS(wFlags);
}
else if(wData2<0)
{
wFlags &=0XFFFC;
wFlags |=0X0002;
_cpu->SetFLAGS(wFlags);
}
}
else
{
ReportState("the 'SUB' instruction can't handle this code");
return;
}
UNSHORT uAddr=_cpu->GetPC();
_cpu->SetPC(uAddr+2);
}
void SLA::Excute(DWORD dwCode)
{
WORD uIP=_cpu->GetIP();
DWORD dw=dwCode & 0X01C00000;//specify the operand mumber
WORD wFlags=_cpu->GetFLAGS();//flag register
if(dw==0x00800000)//2 operand (SLA GR,ADR)
{
DWORD dwTemp1=dwCode & 0X0000FFFF;//get the immediate data
WORD wData1=WORD(dwTemp1);//convert it into 16 bits format
BYTE bIndex=BYTE((dwCode & 0X00070000)>>16);//specify the register index
//the index is stored in the 18-16 bit of dwCode
//shift operation
WORD wTemp1=_cpu->GetGR(bIndex) & 0X8000;
wData1=(_cpu->GetGR(bIndex))<<wData1;
wData1=wData1 & 0X7FFF;
wData1=wData1|wTemp1;
_cpu->SetGR(wData1,bIndex);
//change the flags register
if(wData1>0)
{
wFlags &=0XFFFC;
_cpu->SetFLAGS(wFlags);
}
else if(wData1=0)
{
wFlags &=0XFFFC;
wFlags |=0X0001;
_cpu->SetFLAGS(wFlags);
}
else if(wData1<0)
{
wFlags &=0XFFFC;
wFlags |=0X0002;
_cpu->SetFLAGS(wFlags);
}
}
else if(dw==0X00C00000)//3 operand (SLA GRd,imm,GRs)
{
DWORD dwTemp2=dwCode & 0X0000FFFF;
WORD wData2=WORD(dwTemp2);
BYTE bIndexSrc=BYTE((dwCode & 0X00070000)>>16);
BYTE bIndexDst=BYTE((dwCode & 0X00380000)>>19);
//shift operation
WORD wTemp2=_cpu->GetGR(bIndexDst) & 0X8000;
wData2+=_cpu->GetGR(bIndexSrc);
wData2=_cpu->GetGR(bIndexDst)<<wData2;
wData2=wData2 & 0X7FFF;
wData2=wData2 | wTemp2;
_cpu->SetGR(wData2,bIndexDst);
//change the flags
if(wData2>0)
{
wFlags &=0XFFFC;
_cpu->SetFLAGS(wFlags);
}
else if(wData2=0)
{
wFlags &=0XFFFC;
wFlags |=0X0001;
_cpu->SetFLAGS(wFlags);
}
else if(wData2<0)
{
wFlags &=0XFFFC;
wFlags |=0X0002;
_cpu->SetFLAGS(wFlags);
}
}
else
{
ReportState("the 'SLA' instruction can't handkle this code");
return;
}
UNSHORT uAddr=_cpu->GetPC();
_cpu->SetPC(uAddr+2);
}
void SRA::Excute(DWORD dwCode)
{
WORD uIP=_cpu->GetIP();
DWORD dw=dwCode & 0X01C00000;//specify the operand mumber
WORD wFlags=_cpu->GetFLAGS();//flag register
if(dw==0x00800000)//2 operand (SRA GR,ADR)
{
DWORD dwTemp1=dwCode & 0X0000FFFF;//get the immediate data
WORD wData1=WORD(dwTemp1);//convert it into 16 bits format
BYTE bIndex=BYTE((dwCode & 0X00070000)>>16);//specify the register index
//the index is stored in the 18-16 bit of dwCode
//shift operation
wData1=(_cpu->GetGR(bIndex))>>wData1;
_cpu->SetGR(wData1,bIndex);
//change the flags register
if(wData1>0)
{
wFlags &=0XFFFC;
_cpu->SetFLAGS(wFlags);
}
else if(wData1=0)
{
wFlags &=0XFFFC;
wFlags |=0X0001;
_cpu->SetFLAGS(wFlags);
}
else if(wData1<0)
{
wFlags &=0XFFFC;
wFlags |=0X0002;
_cpu->SetFLAGS(wFlags);
}
}
else if(dw==0X00C00000)//3 operand (SRA GRd,imm,GRs)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -