flycast/core/hw/holly/holly_intc.cpp

218 lines
3.8 KiB
C++
Raw Normal View History

2013-12-19 17:10:14 +00:00
#include "holly_intc.h"
2020-03-28 16:58:01 +00:00
#include "sb.h"
#include "hw/sh4/sh4_interrupts.h"
2013-12-19 17:10:14 +00:00
/*
ASIC Interrupt controller
2013-12-19 17:10:14 +00:00
part of the holly block on dc
*/
//asic_RLXXPending: Update the intc flags for pending interrupts
static void asic_RL6Pending()
2013-12-19 17:10:14 +00:00
{
bool t1=(SB_ISTNRM & SB_IML6NRM)!=0;
bool t2=(SB_ISTERR & SB_IML6ERR)!=0;
bool t3=(SB_ISTEXT & SB_IML6EXT)!=0;
InterruptPend(sh4_IRL_9,t1|t2|t3);
}
static void asic_RL4Pending()
2013-12-19 17:10:14 +00:00
{
bool t1=(SB_ISTNRM & SB_IML4NRM)!=0;
bool t2=(SB_ISTERR & SB_IML4ERR)!=0;
bool t3=(SB_ISTEXT & SB_IML4EXT)!=0;
InterruptPend(sh4_IRL_11,t1|t2|t3);
}
static void asic_RL2Pending()
2013-12-19 17:10:14 +00:00
{
bool t1=(SB_ISTNRM & SB_IML2NRM)!=0;
bool t2=(SB_ISTERR & SB_IML2ERR)!=0;
bool t3=(SB_ISTEXT & SB_IML2EXT)!=0;
InterruptPend(sh4_IRL_13,t1|t2|t3);
}
void asic_RaiseInterrupt(HollyInterruptID inter)
{
u8 type = inter >> 8;
u32 mask = 1 << (u8)inter;
switch(type)
{
case 0:
SB_ISTNRM |= mask;
break;
case 1:
SB_ISTEXT |= mask;
break;
case 2:
SB_ISTERR |= mask;
break;
}
asic_RL2Pending();
asic_RL4Pending();
asic_RL6Pending();
2013-12-19 17:10:14 +00:00
}
static u32 Read_SB_ISTNRM(u32 addr)
2013-12-19 17:10:14 +00:00
{
2020-03-28 16:58:01 +00:00
/* Note that the two highest bits indicate
* the OR'ed result of all the bits in
* SB_ISTEXT and SB_ISTERR, respectively,
* and writes to these two bits are ignored. */
u32 tmp = SB_ISTNRM & 0x3FFFFFFF;
2013-12-19 17:10:14 +00:00
if (SB_ISTEXT)
tmp|=0x40000000;
2013-12-19 17:10:14 +00:00
if (SB_ISTERR)
tmp|=0x80000000;
2013-12-19 17:10:14 +00:00
return tmp;
}
static void Write_SB_ISTNRM(u32 addr, u32 data)
2013-12-19 17:10:14 +00:00
{
2020-03-28 16:58:01 +00:00
/* writing a 1 clears the interrupt */
SB_ISTNRM &= ~data;
2013-12-19 17:10:14 +00:00
asic_RL2Pending();
asic_RL4Pending();
asic_RL6Pending();
}
void asic_CancelInterrupt(HollyInterruptID inter)
{
u8 type = inter >> 8;
u32 mask = ~(1 << (u8)inter);
switch (type)
{
case 0:
SB_ISTNRM &= mask;
break;
case 1:
SB_ISTEXT &= mask;
break;
case 2:
SB_ISTERR &= mask;
break;
}
2013-12-19 17:10:14 +00:00
asic_RL2Pending();
asic_RL4Pending();
asic_RL6Pending();
}
static void Write_SB_ISTEXT(u32 addr, u32 data)
2013-12-19 17:10:14 +00:00
{
//nothing happens -- asic_CancelInterrupt is used instead
}
static void Write_SB_ISTERR(u32 addr, u32 data)
2013-12-19 17:10:14 +00:00
{
SB_ISTERR &= ~data;
asic_RL2Pending();
asic_RL4Pending();
asic_RL6Pending();
}
static void Write_SB_IML6NRM(u32 addr, u32 data)
2013-12-19 17:10:14 +00:00
{
SB_IML6NRM=data;
asic_RL6Pending();
}
static void Write_SB_IML4NRM(u32 addr, u32 data)
2013-12-19 17:10:14 +00:00
{
SB_IML4NRM=data;
asic_RL4Pending();
}
static void Write_SB_IML2NRM(u32 addr, u32 data)
2013-12-19 17:10:14 +00:00
{
SB_IML2NRM=data;
asic_RL2Pending();
}
static void Write_SB_IML6EXT(u32 addr, u32 data)
2013-12-19 17:10:14 +00:00
{
SB_IML6EXT=data;
asic_RL6Pending();
}
static void Write_SB_IML4EXT(u32 addr, u32 data)
2013-12-19 17:10:14 +00:00
{
SB_IML4EXT=data;
asic_RL4Pending();
}
static void Write_SB_IML2EXT(u32 addr, u32 data)
2013-12-19 17:10:14 +00:00
{
SB_IML2EXT=data;
asic_RL2Pending();
}
static void Write_SB_IML6ERR(u32 addr, u32 data)
2013-12-19 17:10:14 +00:00
{
SB_IML6ERR=data;
2013-12-19 17:10:14 +00:00
asic_RL6Pending();
}
static void Write_SB_IML4ERR(u32 addr, u32 data)
2013-12-19 17:10:14 +00:00
{
SB_IML4ERR=data;
2013-12-19 17:10:14 +00:00
asic_RL4Pending();
}
static void Write_SB_IML2ERR(u32 addr, u32 data)
2013-12-19 17:10:14 +00:00
{
SB_IML2ERR=data;
2013-12-19 17:10:14 +00:00
asic_RL2Pending();
}
void asic_reg_Init()
{
sb_rio_register(SB_ISTNRM_addr,RIO_FUNC,&Read_SB_ISTNRM,&Write_SB_ISTNRM);
sb_rio_register(SB_ISTEXT_addr,RIO_WF,0,&Write_SB_ISTEXT);
sb_rio_register(SB_ISTERR_addr,RIO_WF,0,&Write_SB_ISTERR);
//NRM
//6
sb_rio_register(SB_IML6NRM_addr,RIO_WF,0,&Write_SB_IML6NRM);
//4
sb_rio_register(SB_IML4NRM_addr,RIO_WF,0,&Write_SB_IML4NRM);
//2
sb_rio_register(SB_IML2NRM_addr,RIO_WF,0,&Write_SB_IML2NRM);
//EXT
//6
sb_rio_register(SB_IML6EXT_addr,RIO_WF,0,&Write_SB_IML6EXT);
//4
sb_rio_register(SB_IML4EXT_addr,RIO_WF,0,&Write_SB_IML4EXT);
//2
sb_rio_register(SB_IML2EXT_addr,RIO_WF,0,&Write_SB_IML2EXT);
//ERR
//6
sb_rio_register(SB_IML6ERR_addr,RIO_WF,0,&Write_SB_IML6ERR);
//4
sb_rio_register(SB_IML4ERR_addr,RIO_WF,0,&Write_SB_IML4ERR);
//2
sb_rio_register(SB_IML2ERR_addr,RIO_WF,0,&Write_SB_IML2ERR);
}
void asic_reg_Term()
{
}
//Reset -> Reset - Initialise to default values
2019-07-10 15:25:11 +00:00
void asic_reg_Reset(bool hard)
2013-12-19 17:10:14 +00:00
{
}