📄 interruptcontroller.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 + -