SMOOTHER DLI's

Paul Lay shows how to get rid of the keyboard glitch

If you have written any programs that use Display List Interrupts, you may have noticed that you often get 'flashes' or interference with the DLI when using the keyboard or during other processing. This is a well-known problem and has come to be known as 'the keyboard glitch'. It seems strange that no one seems to have figured out a way of programming round this. Consider the following extract from Mapping The Atari.

"One small problem with using DLI's is that the keyboard 'click' routine interferes with the DLI by throwing off the timing, since the click is provided by several calls to the WSYNC register at 54282. Chris Crawford discusses several solutions in De Re Atari, but the easiest of them is not to allow input from the keyboard!"

That's not much use if you want a complex game to use the keyboard as well as a joystick, so let's have a look to see what else we can do. Firstly consider why the glitch occurs in the first place. It is because a STA WSYNC occurs in some other process which interferes with the DLI timing. During a DLI no other interrupts can occur so the interfering STA WSYNC must occur outside the DLI. If therefore we could synchronise directly to the display during a DLI, the glitch problem would be resolved. We can in fact do this by starting a DLI early, then waiting for the vertical line counter (VCOUNT) to reach the required scan line value before performing the normal DLI processing.

As an example, let's consider the case where a DLI is to alter the foreground and background colour registers in the middle of a Graphics O display. Firstly we must determine the value of VCOUNT for the scan line at which we wish our DLI routine to execute. VCOUNT operates in double line resolution and for every Graphics O mode line we increment VCOUNT by 4. After 12 Graphics O mode lines, therefore, VCOUNT will have been incremented by 4*12=48. The value of VCOUNT just before the first scan line is 15 and therefore the value of V COUNT for the mid-point of the screen is 15 + 48 = 63. The following lines are inserted at the beginning of the DLI after saving any register values onto the stack.

SCANLINESYNC
LDA VCOUNT
CMP #63
BNE SCANLINESYNC
STA WSYNC

Notice that we have tagged a STA WSYNC onto the end. This is because VCOUNT operates in double line resolution and the loop therefore terminates one scan line too early (the STA WSYNC rectifies this).

All that now remains is to set where the DLI occurs in the display list. Normally for a DLI to occur in the middle of a Graphics O display we would set bit 7 of DL+16. The interrupt must now, however, occur some time before this so we set bit 7 of DL+15. It could in fact be set at any point prior to DL+16 but DL+15 is the most efficient in terms of processor utilisation.

The DLI timing problem is now solved, however there is a further problem with respect to DLI's which isn't often considered and that is all shadow registers are copied to their hardware counterparts during the non-critical stage of the Operating System's immediate VBI (where interrupts are enabled). If an IRQ occurs during this period, the hardware registers will not be updated. Thus if a colour register is altered in the middle of the screen and the hardware registers are not updated because an IRQ occurs, then that register will remain momentarily in the colour it was set to by the VBI.

We can overcome this easily by setting up our own immediate VBI to copy the shadow registers into the hardware registers, which is called by the operating system during its immediate VBI critical stage, and hence is always executed. This is how animation is performed whilst games are loading, for example on Activision's Decathlon or even Bignose Software's Sprong! In the example program I have given I have only updated the colour registers in my immediate VBI as these are all I have changed. If any other shadow registers are altered in a DLI then they too should be updated as part of the immediate VBI.

You will find a simple BASIC listing and the source code with this article. I hope that my explanation is not too confusing and that you can put the principles into practice in your own programs. Although it may seem complicated, it is basically only four machine code instructions added to a normal DLI together with a very straightforward immediate VBI.