Tuesday, 26 June 2012

In Which We Go Code-Blind


I traced and fixed the odd multiple-line cursor increment bug quite quickly after my last post - embarrassingly, it was a simple mistake; I'd forgotten to call TESTMULT, which is a little routine that checks to see whether a key has been held down across multiple keyscan cycles and takes action according to a couple of simple rules. Some keys don't care, like Shift; others must suppress the repeated keypress detection, like Caps Lock; and most must determine whether key-repeat is enabled, and then wait a short interval before auto-repeating. If it's not called, then the keypress is detected every IRQ, and the result is an implicit (very fast) repeat - so of course hitting Return without calling it was actually causing 3 or 4 cycles of keyscan detection to register the key, and moving the cursor accordingly. Oops. ;)

What I've been looking at fixedly since then is a silly little redraw bug - sometimes, the cursor doesn't get 'undrawn' from it's old position before being drawn at it's new one. There are a couple of conditions surrounding this logic, which essentially cause the undraw to be skipped if the cursor isn't visible or active at the time of the reposition event. So if it's in the 'off' phase of the blink cycle (assuming blink is enabled) there's no need to undraw it, and equally if the cursor is inactive (it can be disabled so that activities like rendering text to the screen don't have to update the cursor position after every character) then it's implicitly invisible and again there's no need to undraw it. Somewhere in this quite straightforward bit of logic there's an edge-case tripping me up, because every once in a while, it thinks the undraw isn't needed when it actually is.

I've been staring at this code for about 3 hours now, tracing the path it takes using the XVIC monitor, and I've spotted a scenario in which the visibility bit is clear when it should be set - which of course tells the code not to do the undraw because the cursor is (or should be) undrawn already. But the bit-setting is incorrect - the cursor is in fact entirely visible. So the undraw logic is actually working as designed, but something somewhere else is messing with the visibility bit, and that's proving a challenge to find; the trouble is, I've been looking at this for so long now that all I see is blonde, brunette, red-head... :)

Ah well, it'll make itself apparent shortly, I expect - it must be something really simple and silly, and I will no doubt kick myself soundly when I finally discover it. On we go.

No comments:

Post a Comment