@@ -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
407405static 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