#include "types.h" #include "holly_intc.h" #include "hw/sh4/sh4_interrupts.h" #include "hw/holly/sb.h" #include "hw/maple/maple_if.h" /* ASIC Interrupt controller part of the holly block on dc */ //asic_RLXXPending: Update the intc flags for pending interrupts void asic_RL6Pending() { 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); } void asic_RL4Pending() { 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); } void asic_RL2Pending() { 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); } //Raise interrupt interface void RaiseAsicNormal(HollyInterruptID inter) { if (inter==holly_SCANINT2) maple_vblank(); u32 Interrupt = 1<<(u8)inter; SB_ISTNRM |= Interrupt; asic_RL2Pending(); asic_RL4Pending(); asic_RL6Pending(); } void RaiseAsicExt(HollyInterruptID inter) { u32 Interrupt = 1<<(u8)inter; SB_ISTEXT |= Interrupt; asic_RL2Pending(); asic_RL4Pending(); asic_RL6Pending(); } void RaiseAsicErr(HollyInterruptID inter) { u32 Interrupt = 1<<(u8)inter; SB_ISTERR |= Interrupt; asic_RL2Pending(); asic_RL4Pending(); asic_RL6Pending(); } void asic_RaiseInterrupt(HollyInterruptID inter) { u8 m=inter>>8; switch(m) { case 0: RaiseAsicNormal(inter); break; case 1: RaiseAsicExt(inter); break; case 2: RaiseAsicErr(inter); break; } } u32 Read_SB_ISTNRM(u32 addr) { /* 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; if (SB_ISTEXT) tmp|=0x40000000; if (SB_ISTERR) tmp|=0x80000000; return tmp; } void Write_SB_ISTNRM(u32 addr, u32 data) { /* writing a 1 clears the interrupt */ SB_ISTNRM &= ~data; asic_RL2Pending(); asic_RL4Pending(); asic_RL6Pending(); } void asic_CancelInterrupt(HollyInterruptID inter) { SB_ISTEXT&=~(1<<(u8)inter); asic_RL2Pending(); asic_RL4Pending(); asic_RL6Pending(); } void Write_SB_ISTEXT(u32 addr, u32 data) { //nothing happens -- asic_CancelInterrupt is used instead } void Write_SB_ISTERR(u32 addr, u32 data) { SB_ISTERR &= ~data; asic_RL2Pending(); asic_RL4Pending(); asic_RL6Pending(); } void Write_SB_IML6NRM(u32 addr, u32 data) { SB_IML6NRM=data; asic_RL6Pending(); } void Write_SB_IML4NRM(u32 addr, u32 data) { SB_IML4NRM=data; asic_RL4Pending(); } void Write_SB_IML2NRM(u32 addr, u32 data) { SB_IML2NRM=data; asic_RL2Pending(); } void Write_SB_IML6EXT(u32 addr, u32 data) { SB_IML6EXT=data; asic_RL6Pending(); } void Write_SB_IML4EXT(u32 addr, u32 data) { SB_IML4EXT=data; asic_RL4Pending(); } void Write_SB_IML2EXT(u32 addr, u32 data) { SB_IML2EXT=data; asic_RL2Pending(); } void Write_SB_IML6ERR(u32 addr, u32 data) { SB_IML6ERR=data; asic_RL6Pending(); } void Write_SB_IML4ERR(u32 addr, u32 data) { SB_IML4ERR=data; asic_RL4Pending(); } void Write_SB_IML2ERR(u32 addr, u32 data) { SB_IML2ERR=data; 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 void asic_reg_Reset(bool hard) { }