Hourglass / OS_Byte 19 issue
Jon Abbott (1421) 2651 posts |
I’ve been looking into why Hourglass_On locks the machine solid when I install my GraphicsV driver and have tracked it down to the Hourglass Module TickerV code issuing OS_Byte 19 with IRQ’s disabled. This raises a few questions: 1. Does Hourglass need to issue OS_Byte 19 on anything beyond IOMD? |
Jeffrey Lee (213) 6048 posts |
Nope, that’s not it. MyTickRoutine (which is the only thing calling ProgramPointer) enables IRQs – look for the use of the WritePSRc macro (switches from IRQ mode with IRQs disabled to SVC mode with IRQs enabled) Also OS_Byte 19 forcibly enables interrupts, so even if it was being called with IRQs disabled it should still operate correctly. Considering that the kernel relies on the ‘CFStime’ counter to work out when the VSync interrupt has occurred, chances are you’re in a situation where that variable isn’t being updated for some reason. Possibly your driver isn’t making reporting VSync events via GraphicsV. Or if your driver doesn’t generate VSyncs, possibly the FalseVSyncIRQ routine isn’t running (it runs off of TickerV). Or possibly the kernel is confused and hasn’t registered the fake VSync handler yet – at the moment I think the only place the handler is registered/deregistered is in PushModeInfo, which gets called during mode changes, but also in a few other situations (I think maybe OS_CheckModeValid. A more appropriate place for setting up the fake VSync would probably be in HardwareModeChange, but I haven’t got round to fixing that yet). |
Jon Abbott (1421) 2651 posts |
Indeed, after lots more testing I’ve tracked it down to RTSupport not calling my VSync generator whilst Hourglass’s TickerV code is executing. I’m not sure how to get around that. |
Jeffrey Lee (213) 6048 posts |
Yeah, that sounds a bit nasty. We could get rid of the OS_Byte call from within ProgramPointer by changing the module to do all the pointer/palette updates from within EventV (listening out for the VSync event). That would fix the problem you’re currently seeing, but maybe there’s more code elsewhere which also calls OS_Byte 19 from an interrupt handler. So I’m not sure what the best solution would be in general (make OS_Byte 19 return immediately if called while in interrupt context? find a different way of implementing your VSync generator?) |
Jon Abbott (1421) 2651 posts |
The solution I’m looking at, is to intercept OS_Byte 19 and wait 2cs instead of waiting for a VSync, whilst I’m generating fake VSync. As you rightly point out, other code could cause OS_Byte 19 to stall, if its called from an interrupt context. |
Jon Abbott (1421) 2651 posts |
Changing to this method stops the machine locking in this example: However, the following code will still lock the machine at the point the Hourglass is first displayed (~half a sec): The machine appears to permanently be in an interrupt context whilst the Hourglass is displayed… IRQsema is never 0 in the OS_Byte 19 handler. |
Jon Abbott (1421) 2651 posts |
I’ve found a somewhat messy workaround, by coding the OS_Byte 19 handler as follows: IF re-entrant THEN ignore SWI Essentially the Hourglass stalls RTSupport whilst it’s displayed and sitting in OS_Byte 19. Can OS_Byte 19 can be made to allow other processes to continue whilst its called from an interrupt context? Surely there’s a knock on effect to any code sitting under RTSupport whilst the Hourglass is on? |
Jeffrey Lee (213) 6048 posts |
That doesn’t sound right. WAIT uses OS_Byte 19 (I think!), so whenever that’s issued IRQsema should be zero.
I suspect the best option is to just make OS_Byte 19 return immediately if called from an interrupt. If you’re doing something that needs synchronising with the display, either do it from the foreground, or from within EventV. Blocking the foreground and RTSupport routines is just bad form.
Only when the mouse palette needs changing. Normally this would only be when the hourglass appears and disappears, not while it’s animating. |