Display Lists Pt. 3

A tutorial by Steve Pedler


Issue 20

Mar/Apr 86

Next Article >>

<< Prev Article




One of the most spectacular effects possible on any micro is fine scrolling. I recently read a review for a BBC micro program in which the fine scrolling was praised. The reviewer went on to say that this effect had needed the shifting of more than 20,000 bytes! The same scrolling could be achieved on an Atari by manipulating just a couple of dozen bytes as the Atari has inbuilt hardware scrolling - a feature otherwise found on much more expensive machines. As you will know, scrolling can take place in two directions, horizontal and vertical (the frequently seen diagonal scrolling is a combination of the two). Let us consider vertical scrolling first, as it is slightly easier to implement than the horizontal effect.

Coarse scrolling (the type you see when LISTing a BASIC program) is easily achieved by manipulation of the DL, as demonstrated in Listing 17. If you have followed and understood this article so far, you should find it easy to see how this program works. It first points the display memory to the lowest RAM of the Atari then coarse scrolls over the entire memory space of the computer. You will remember that the LMS instruction at the start of any DL points to the first byte of screen memory, which is displayed at the top lefthand corner of the screen. By adding the number of bytes used in one mode line (40 bytes in the case of Graphics 0) to the LMS operand bytes we cause the display to move up by one line. Repeating this process makes the display scroll upwards.

Listing 17

Now coarse scrolling is not particularly attractive, and it would be much better if we could scroll over a smaller distance, such as one scan line at a time. The Atari provides the facility to do just this - the register VSCROL at location 54277 (D405 hex). POKEing this register with a number from zero to 16 causes the display to scroll over that number of scan lines. However, when fine scrolling using this register, you must carry out one further step, that is to set the vertical fine scroll bits in the DL. This is done by adding 32 to the instruction code for each mode line you wish to scroll. Unless you do this, altering VSCROL will have no effect. Note that you do not need to set the vertical scroll bit on every mode line, unless of course you want the whole screen to scroll. Once this is done, incrementing VSCROL scrolls the screen upwards, decrementing VSCROL scrolls the screen down.

There is however one snag, which you may already have spotted. VSCROL can only be POKEd with a number of16 or less. How then do we scroll over a larger distance than 16 scan lines? The solution is in fact quite simple. We fine scroll over the number of scan lines needed to make up one mode line minus one (using VSCROL) then reset VSCROL and complete the scroll by carrying out a coarse scroll. In case that isn't entirely clear (!), Figure 2 should provide additional clarification. I am sure that many of you will have seen this little diagram or something similar in other articles on scrolling, but I repeat it here as it is so useful.

Figure 2. Use of continued fine and course scrolling with register VSCROL

Downward scrolling is achieved by reversal of the process. Set VSCROL initially not to zero but to the number of scan lines making up one mode line (see Table 1) then decrement VSCROL to one. The scroll is completed by decrementing the LMS operand bytes by the appropriate number, resetting VSCROL at the same time.

You can fine scroll from BASIC but the results are not particularly good. Listing 18 is an example. The program first sets the vertical fine scroll bits on every line in the DL (line 40) and then scrolls the display using combined fine and coarse scrolling as described above. Straightaway you will notice a couple of problems. Firstly, if you look carefully you will see that the bottom line of the display does not scroll in properly but jumps into place. This can be avoided very easily by not setting the vertical fine scroll bit on the last line of your scrolling display (in this case, the bottom line of the screen). This allows the last line to act as a buffer for the next line to scroll in. To see this, change the FOR...NEXT loop in line 40 to read FOR J=6 TO 27, then rerun the program. The last line now scrolls smoothly into place.

Listing 18

Secondly, notice that frequently the screen jumps or flashes. This is an unavoidable effect of fine scrolling from BASIC and occurs when VSCROL is changed while the screen is being drawn. This distracts Antic and causes the unpleasant glitches. The only solution is to change VSCROL during the vertical blank period, which can only be done in machine language. If you now add Listing 19 to Listing 18 you will finally get a smooth fine scroll demonstration. This is a simple VBI routine to scroll the display, and the assembler source code is provided in Listing 20.

Listing 19

This demonstration does however show one last problem associated with vertical fine scrolling. As you watch the display, you will see that every so often the display suddenly changes. This is due to the limitation of Antic's memory counter discussed earlier in this article, namely that it cannot cross a 4K memory boundary. In a real application, if you wished (and you probably would) to scroll over an area of greater than 4K, then one way around the problem would be to organise the screen memory in discrete blocks starting at 4K RAM boundaries. Then, on approaching the end of a 4K block, you would change the LMS operand bytes in the DL to point to the next block, thus resetting the memory counter. Of course, you would have to ensure that the first screen of the new block was the same as the last screen of the previous block or the picture would appear to suddenly change completely!

As you can see then, more than anything else scrolling demands precise memory management - something you don't normally have to worry much about. This is further emphasised when setting up for horizontal scrolling.

The difficulty is that while graphics mode lines appear completely separate on the screen, they are not so in RAM. The bytes for one line follow directly on from those of the previous line. Thus, if you attempted (for example) to scroll the third line of a screen, the contents of line four would scroll into line three, line five into line four, and so on. However, by organising the screen memory differently it is easy to get around this problem, and horizontal scrolling then becomes easier if anything than vertical scrolling. What you do is direct each line you wish to scroll to its own separate area of memory, and this is done by setting an LMS instruction on each line to be scrolled. As always, an example helps to clarify the position.

Listing 21 arranges for a line of text in Graphics 2 to horizontally coarse scroll across the screen. It first sets up a new DL in page six, then the 6th mode line down is directed to a different memory area (actually page zero) than the rest of the screen by its own LMS code. The 7th mode line is then directed back to the regular screen memory by another LMS instruction. Incrementing the LMS operand low-byte for the 6th mode line causes right-to-left scrolling, and when the end of page zero is reached the pointer is directed back to the start of the page. One point to note here, location 255 is of course the last location in page zero, but since the mode line itself takes 20 bytes, we use 255-20=235 as the limiting point for return to the start of the page. If you look carefully, you can see that the display suddenly changes completely when the return to the start of the page occurs. As an exercise, you might like to arrange this program so that each mode line displays and scrolls a different page in memory. If you get stuck, De Re Atari (page 6-4) contains just such a program to study.

Listing 21

Once memory is arranged in this way, fine scrolling can be implemented in the same fashion as vertical fine scrolling. The register to use is HSCROL (location 54276, D404 hex) which will scroll up to 16 colour clocks horizontally in an identical manner and with the same limitations as VSCROL. To scroll over a large area therefore, we must combine fine and coarse scrolling as before. To effect horizontal fine scrolling, the appropriate lines of the DL must have the horizontal fine scroll bit set (add 16 to the DL mode line instruction). A slight complication is that incrementing HSCROL scrolls the line from left to right, while as we have seen incrementing the LMS operand moves it from right to left. To fine scroll the same demonstration as in Listing 21, we first set HSCROL to eight (Graphics 2 characters are eight colour clocks wide) and decrement HSCROL to do the scroll. Unfortunately, setting HSCROL to eight would move the line one character to the right. To bring the line back to its correct starting position therefore we set the LMS low-byte initially to one rather than zero. To see how this works, add Listing 22 to Listing 21 and rerun the program. Once again, we get those unpleasant glitches, and again we can only get rid of these by scrolling during the vertical blank interval.

Listing 22

Before bringing in a VBI routine to do this, let's look at a slightly more practical demonstration. Listing 23 sets up a DL to scroll one line of Graphics 2 text as before, but this time the text is a message that will scroll across the screen. Line 30 reserves some memory (0.5K) to hold our message, and the subroutine at line 270 POKEs the internal character codes of the message, held in A$, into the reserved area. Incidentally, 512 bytes may not sound a lot, but since Graphics 2 screens only use 20 bytes per line you can scroll through the equivalent of 12 screens with the use of just 3K of memory. I believe that Chris Crawford used Graphics 2 for his celebrated 'Eastern Front' map, the surprisingly small amount of memory used in scrolling text modes explains how such a large map and complex program fits into 16K.

Listing 23

Take a look now at lines 300 to 320 where A$ is defined. You will see that the string starts with two blank spaces. Why is this? Well, remember that when vertically scrolling a display we dedicated one mode line to act as a buffer. Setting the horizontal scroll bits in the DL makes Antic take an extra 20% of memory per mode line to act as a scrolling buffer (in the case of a 20-byte line, four extra bytes). On a normal width playfield, these four bytes - two at each end of the line - are not displayed on the screen, but we have to take them into account all the same. If we didn't do this by starting the scrolling memory area with two extra characters (blanks because we don't want them to be seen) then we would lose the first two characters of the message. Secondly, you will have noticed that the last 20 characters of the string are identical to the first 20 characters. This is because for the purposes of this demonstration we want the message to repeat over and over again. However, directing the display memory back to the start of the message when the end is reached would result in a sudden change in the display. Try changing the last 20 characters of the string to see what I mean. The way to avoid this is to make the end of the scrolling memory identical to the start. Then, when the memory pointer is redirected, no apparent change in the display is seen. You should always do this if you want a wraparound display (the same applies to vertical scrolling as well). Finally, the program uses a simple VBI routine to perform the scroll (source code in Listing 24).

Well, that's about it! I have tried to cover (in at least sufficient detail to get you started) the various effects possible by altering and manipulating the display list. I have used many sources for this article, but the most informative were as follows:

De Re Atari (various authors) from Atari Inc. See chapters 2, 5, and 6.

Mapping The Atari by Ian Chadwick, from Compute! books.

Computer Animation Primer by David Fox and Mitchell Waite from Byte Books. See chapters 5, 8, and 9.

First Book of Atari Graphics (various authors) from Compute! Books. See chapter 2.

Tricky Tutorial 1: The Display List from Santa Cruz educational software (manual and cassette/disk).

Your Atari Computer by Lon Poole, Martin McNiff and Steven Cook from Osborne/McGraw Hill. See chapter 9, pp. 294-306.