Thursday, 28 February 2013

In Which We Regain Cursor Control


After a fairly short but intense burst of activity, I can now proudly assert that VIC++ once again has a cursor. A small thing (literally and figuratively) but a minor milestone nonetheless, as it marks a notable step along the path to a functioning demo version - as well as being, internally, a much slicker version of the code I wrote to do this last year.

I also slipped the logic back into the IRQ handler to do additional 'opportunity' passes over the dirty-row routine to increase screen rendering speed when appropriate. This has the same basic mechanics as before, whereby the OS dynamically decides whether to call the row-refresh routine more than once per frame if there's time - but now there's a further layer of sophistication by which the user has an overriding control option. Here's how it works:

At the simplest level, we know that in PAL mode we have 22,150 cycles per frame and for NTSC we have 16,963 cycles. The dirty-row glyph render routine takes just over 7,000 cycles to completely draw a line with no attributes or with inverse attributes, and about 7,600 cycles to draw a line with underline attributes - which means that in PAL mode we have time to refresh either two or three lines per frame (three if no rows have underline enabled, two if either or both do have underline enabled) and in NTSC mode we can always refresh two rows. So for PAL mode the IRQ routine does a little check after each rendering pass to see if the underline attribute was used, and will repeat the call to the refresh routine once or twice depending on that. In NTSC mode, it always repeats the call to the refresh routine once, as there's always time for two passes but never for three.

I have now introduced a method by which the user can influence this process, essentially restricting the automatic mechanism by defining a 'rate-limiter' which has values from zero to two (NTSC) or three (PAL). This acts as an override to the automatic refresh-repeat, forcibly preventing the IRQ routine from repeating as many times as it might decide to and instead only repeating as many times as the user stipulates. You might be asking, "why bother?" Well, it all comes down to CPU-time - implicitly, if the IRQ routine decides to repeat the refresh process in a given frame to update more than one line, it will consume a proportionately larger percentage of the CPU-time during that frame (and subsequent frames, if there are many dirty rows to be refreshed). But the user might be running code that could suffer from this, and may wish to adjust the balance between screen-refresh speed and available CPU-time for their code - so they can now specify that the system will refresh the screen more slowly than it could, but thereby leave more CPU per frame for user-code.

This rate-limiter, as mentioned, goes from zero to the maximum allowed per video mode - so if it's left at the default of 3 for PAL mode, the IRQ handler will do three refresh passes if it can. Changing to 2 means that it'll now only ever do two passes even if there was time for a third; a setting of 1 means, of course, only one row refresh per frame, and finally 0 means no refreshes at all - it's possible for the user to say 'do not update the screen at all until I say so, because my code needs all the available CPU time'. There's a little setrefresh routine which can be called with the desired value in .A to set the limiter - it checks to make sure the value is valid for the video mode (so you can't set NTSC to 3, for example, or PAL to 4) and just defaults to the appropriate maximum if not.

So, with that done and the cursor back, I'm somewhat torn as to what to do next. I could release this now, just as a taster to prove I'm not making all this up and that there really is something that exists and does what I've been saying it does - or I could hold-off until I've tackled the last couple of 'optional' items on the to-do list; or I could forge ahead and get some keyboard-handling logic in place so you can at least interact with the system and move the cursor around the screen, if nothing else.

What to do? Hmm...

No comments:

Post a Comment