void UpdateTMU_chan(u32 clc) { //if chanel is on if ((TMU_TSTR & tmu_ch_bit[ch])!=0) { //count :D tmu_prescaler[ch]+=clc; u32 steps=tmu_prescaler[ch]>>tmu_prescaler_shift[ch]; if (steps>tmu_regs_CNT[ch]) { //remove the 'extra' steps to overflow steps-=tmu_regs_CNT[ch]; //refill the counter tmu_regs_CNT[ch] = tmu_regs_COR[ch]; //raise the interrupt tmu_regs_CR[ch] |= tmu_underflow; InterruptPend(tmu_intID[ch],1); //remove the full underflows (possible because we only check every 448 cycles) //this can be done with a div, but its very very very rare so this is probably faster //THIS can probably be replaced with a verify check on counter setup (havn't seen any game do this) while(steps>tmu_regs_COR[ch]) steps-=tmu_regs_COR[ch]; //steps now has the partial steps needed for update, guaranteeded it won't cause an overflow } //count down tmu_regs_CNT[ch]-=steps; //remove the full steps from the prescaler counter tmu_prescaler[ch]&=tmu_prescaler_mask[ch]; }
//return true if any RL2 interrupt is pending 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); }
//returns true if any RL6 Interrupts are pending 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); }