Skip to content

Commit c70bdf2

Browse files
committed
gx: revise __GXCPInterruptHandler to avoid spurious underflow/overflow IRQs
1 parent 3f270d0 commit c70bdf2

1 file changed

Lines changed: 9 additions & 6 deletions

File tree

libogc/gx.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,6 @@ static void __GXOverflowHandler(void)
389389
_gxoverflowsuspend = 1;
390390
_gxoverflowcount++;
391391
__GX_WriteFifoIntEnable(GX_DISABLE,GX_ENABLE);
392-
__GX_WriteFifoIntReset(GX_TRUE,GX_FALSE);
393392
LWP_SuspendThread(_gxcurrentlwp);
394393
}
395394
}
@@ -399,22 +398,26 @@ static void __GXUnderflowHandler(void)
399398
if(_gxoverflowsuspend) {
400399
_gxoverflowsuspend = 0;
401400
LWP_ResumeThread(_gxcurrentlwp);
402-
__GX_WriteFifoIntReset(GX_TRUE,GX_TRUE);
403401
__GX_WriteFifoIntEnable(GX_ENABLE,GX_DISABLE);
404402
}
405403
}
406404

407405
static void __GXCPInterruptHandler(u32 irq,void *ctx)
408406
{
407+
// Clear spurious pending underflow/overflow IRQs before reading the status register.
408+
// Note that legitimate IRQs are sticky & can't be cleared until the CPU produces or
409+
// the GPU retires commands, respectively.
410+
__GX_WriteFifoIntReset(GX_TRUE, GX_TRUE);
409411
__gx->cpSRreg = _cpReg[0];
410412

411-
if((__gx->cpCRreg&0x08) && (__gx->cpSRreg&0x02))
413+
// Check for underflow/overflow (only one can be active at a time)
414+
if (__gx->cpSRreg & 0x02)
412415
__GXUnderflowHandler();
413-
414-
if((__gx->cpCRreg&0x04) && (__gx->cpSRreg&0x01))
416+
else if (__gx->cpSRreg & 0x01)
415417
__GXOverflowHandler();
416418

417-
if((__gx->cpCRreg&0x20) && (__gx->cpSRreg&0x10)) {
419+
// Check for breakpoint
420+
if ((__gx->cpSRreg & 0x10) && (__gx->cpCRreg & 0x20)) {
418421
__gx->cpCRreg &= ~0x20;
419422
_cpReg[1] = __gx->cpCRreg;
420423
if(breakPtCB)

0 commit comments

Comments
 (0)