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

📄 interruptcontroller.cpp

📁 一款国产的8051模拟器(全部源代码) 本软件是一款8051模拟器
💻 CPP
字号:
// InterruptController.cpp: implementation of the InterruptController class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GlobalVar.h"
//#include "8051class.h"
#include "interruptcontroller.h"

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

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
void IPC_IEIP_CLOCK_HOOK(BYTE  VarNum,unsigned short Clocknum)
{
	var8051[VarNum]->IPC->CheakIRQ();	
}

void IPC_IEIP_HOOK(BYTE  VarNum,int mode,BYTE data)//不要奇怪为什么所有HOOK都指向这里,因为它是第一个HOOK所以不用调用下一个HOOK
{
	if(data&0x9f)//对Bit寻址监控有效
	{
		//var8051[VarNum]->IPC->CheakIRQ();此句错误,不要直接中断,否则会造成将错误的地址压栈,必须延迟一个指令周期
		//var8051[VarNum]->KMsg->CancelCallBackByClocknum(var8051[VarNum]->IPC->IPC_IEIP_BackFunNum,var8051[VarNum]->IPC->IPC_IEIP_BackFun);
		var8051[VarNum]->IPC->CLOCKEVENTPOS.CLOCK_POS=1;
		var8051[VarNum]->KMsg->CallBackAfterRelativeClock(IPC_IEIP_CLOCK_HOOK,&(var8051[VarNum]->IPC->CLOCKEVENTPOS));
		//var8051[VarNum]->IPC->IPC_IEIP_BackFunNum=var8051[VarNum]->KMsg->GetCurrentClockpos()+1;
	}
	return ;
}

InterruptController::InterruptController()
{
	//memset(IRQP,0,5);
	//pIRQP=IRQP;

}

InterruptController::~InterruptController()
{
	

}

int InterruptController::Setinterrupt(BYTE num)
{
	this->SetIRQflag(num,1);
	if(!this->CheakSwitch(num))
	{
		return false;
	}
	if(!this->Cheaklevel(num))
	{
		return false;
	}
	if(num!=RITI)//如果不是串口中断,进行硬件清除中断标志
	{
		this->SetIRQflag(num,0);
	}
	BYTE addrip=IP+(num-IE0);//计算优先级寄存器位地址
	//BYTE CPULevel=mem->GetBit(addrip)+128;//计算CPU应该得到的等级
	mem->CurrentCPULevel++;
	mem->CurrentIRQLevel=num-IRQNUM*(mem->GetBitf(addrip));//计算IRQ优先权
	BYTE buf1=(BYTE)PC;
	BYTE buf2=(BYTE)(PC>>8);
	SP=SP+1;
	mem->SetidataMemBytef(SP,buf1);
	SP=SP+1;                                                                                                                                                                                                                                                                                                                                                                                                                                                                1;
	mem->SetidataMemBytef(SP,buf2);
	switch(num)
	{
	case IE0:
		mem->PCm=0x03;
		break;
	case IE1:
		mem->PCm=0x13;
		break;
	case TF0:
		mem->PCm=0x0b;
		break;
	case TF1:
		mem->PCm=0x1b;
		break;
	case RITI:
		mem->PCm=0x23;
		break;
	default: return false;
	}
	return true;//成功
}

int InterruptController::Setinterrupt(BYTE num, BYTE mode)
{
	if(!this->CheakIRQTriggerMode(num,mode))
	{
		return false;
	}
	Setinterrupt(num);
	return true;//成功
}

int InterruptController::Cheaklevel(BYTE num)
{
	BYTE addrip=IP+(num-IE0);//计算优先级寄存器位地址
	BYTE CPULevel=mem->GetBit(addrip)+128;//计算中断优先权
	if(CPULevel>mem->CurrentCPULevel)
	{
		
		return true;//允许中断
	}
	return false;

}

int InterruptController::SetMem(instruction * pinstc)
{
	//pinst=pinstc;
	mem=pinstc->mem;
	return false;
}

int InterruptController::CheakSwitch(BYTE num)
{
	if(!mem->GetBitf(IE_EA))
	{
		return false;//关中断
	}
	BYTE addrie=IE+(num-IE0);
	if(!mem->GetBitf(addrie))
	{
		return false;//关中断
	}
	return true;
}

int InterruptController::CheakIRQTriggerMode(BYTE num, BYTE mode)
{
	if(num!=IE0&&num!=IE1)
	{
		return true; //除了外部中断,其他中断都没有触发方式这个概念,所以中断允许
	}
	if(num==IE0)
	{
		if(mode==mem->GetBitf(TCON_IT0))
		{
			return true;
		}
		return false;
	}
	if(mode==mem->GetBitf(TCON_IT1))
		{
			return true;
		}
	return false;

}

int InterruptController::SetIRQflag(BYTE num,BYTE flag)
{
	switch(num)
	{
	case IE0:
		mem->SetBitf(TCON_IE0,flag);
		break;
	case IE1:
		mem->SetBitf(TCON_IE1,flag);
		break;
	case TF0:
		mem->SetBitf(TCON_TF0,flag);
		break;
	case TF1:
		mem->SetBitf(TCON_TF1,flag);
		break;
	default: return false;
	}
	return true;

}

int InterruptController::SetSRIRQflag(BYTE num,BYTE flag)
{
	switch(num)
	{
	case TI:
		mem->SetBitf(SCON_TI,flag);
		break;
	case RI:
		mem->SetBitf(SCON_RI,flag);
		break;
	default: return false;
	}
	return true;
}

int InterruptController::CheakIRQ()
{
	//有中断,条件满足,执行中断
	//有中断,条件不满足,退出
	//没有中断,退出
	//如果效率低,试直接引用mem内存
	BYTE IEBUF=mem->GetidataMemBytef(IE)&0x9f;
	if(IEBUF<0x80)//EA=0或所有中断开关位为0,即为关中断,所以返回
	{
		return false;
	}	
	BYTE IRQfalg=mem->GetidataMemBytef(TCON)&0xaa;
	////重新排列中断源,以便于计算
	IRQfalg=IRQfalg>>1;
	IRQfalg=(IRQfalg|(IRQfalg>>3))&0xf;
	if(mem->GetidataMemBytef(SCON)&0x3)
	{
		IRQfalg=IRQfalg|0x10;
	}
	IEBUF=IEBUF&0x1f;//屏蔽EA
	BYTE IEIFBUF=IEBUF&IRQfalg;//有中断标志且开中断
	if(IEIFBUF==0)//没有满足条件的中断发生
	{
		return false;
	}
	BYTE IPBUF=mem->GetidataMemBytef(IP)&0x1f;
	int index=0;
	BYTE IPIEIF=IEIFBUF&IPBUF;
	if(IPIEIF)
	{
		//高优先权级中断
		for(;IPIEIF&0x1;index++)
		{
			IPIEIF=IPIEIF>>1;
		}
	}
	else
	{
		//低级中断
		for(;(IEIFBUF&0x1)==0;index++)
		{
			IEIFBUF=IEIFBUF>>1;
		}
	}
	if(!Cheaklevel(IE0+index))
	{
		return false;
	}
	if(index!=4)//如果不是串口中断,进行硬件清除中断标志
	{
		this->SetIRQflag(IE0+index,0);//2004.4.17修改了此处错误
	}
	BYTE bitip=mem->GetBitf(IP+index);//计算相应中断的优先权
	BYTE CPULevel=bitip+128;//计算CPU应该得到的等级
	mem->CurrentCPULevel=CPULevel;
	mem->CurrentIRQLevel=IE0+index-IRQNUM*bitip;//计算IRQ优先权
	BYTE buf1=(BYTE)PC;
	BYTE buf2=(BYTE)(PC>>8);
	SP=SP+1;
	mem->SetidataMemBytef(SP,buf1);
	SP=SP+1;                                                                                                                                                                                                                                                                                                                                                                                                                                                                1;
	mem->SetidataMemBytef(SP,buf2);
	switch(index)
	{
	case 0:
		mem->PCm=0x03;
		break;
	case 1:
		mem->PCm=0x0b;
		break;
	case 2:
		mem->PCm=0x013;
		break;
	case 3:
		mem->PCm=0x01b;
		break;
	case 4:
		mem->PCm=0x23;
		break;
	default: return false;
	}
	return true;//成功


	return 0;
}

int InterruptController::init()
{
	pKMsg->SetupMemHook(IE,IdataSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(IE_EA,BitSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(IE_EX0,BitSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(IE_ET0,BitSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(IE_EX1,BitSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(IE_ET1,BitSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(IE_ES,BitSpace,Write,IPC_IEIP_HOOK);

	pKMsg->SetupMemHook(IP,IdataSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(IP_PX0,BitSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(IP_PT0,BitSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(IP_PX1,BitSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(IP_PT1,BitSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(IP_PS,BitSpace,Write,IPC_IEIP_HOOK);

	pKMsg->SetupMemHook(TCON,IdataSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(TCON_IE0,BitSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(TCON_IE1,BitSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(TCON_TF0,BitSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(TCON_TF1,BitSpace,Write,IPC_IEIP_HOOK);
	//pKMsg->SetupMemHook(IP_PS,BitSpace,Write,IPC_IEIP_HOOK);
	CLOCKEVENTPOS.CLOCK_POS=0;
	CLOCKEVENTPOS.EVENT_QUEUE_POS=0;
/*	pKMsg->SetupMemHook(IP,IdataSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(IP_PX0,BitSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(IP_PT0,BitSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(IP_PX1,BitSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(IP_PT1,BitSpace,Write,IPC_IEIP_HOOK);
	pKMsg->SetupMemHook(IP_PS,BitSpace,Write,IPC_IEIP_HOOK);*/
	//pKMsg->SetupMemHook(IE_ET2,IdataSpace,Write,IPC_IEIP_HOOK);//MCS52的定时器2中断开关,
	return 1;
}

⌨️ 快捷键说明

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