Display Lists Pt.1

A tutorial by Steve Pedler

 

Issue 18

Nov/Dec 85

Next Article >>

<< Prev Article

 

 

Many of the superb graphic displays of which we all know the Atari is capable depend on altering a set of instructions in RAM called the display list. This article is devoted to the display list (DL) and how to modify it for our own purposes. The article contains a number of demonstration programs which are explained in the text and in REM statements in the program itself. When typing them in, always type in the lines with REMs in them (at least the line number plus REM, if not the whole line) as in some cases these lines are used for GOTO and GOSUB statements. I would recommend that when reading the article the program listings are studied along with the text.

THE TV-SCREEN DISPLAY

Virtually every display list article I have ever seen starts off with a discussion of how the TV display is produced. This one is no exception, so those readers who already know how this works can skip to the next section.

An image is produced on a television screen by a stream of electrons which strike a phosphor coated surface causing it to glow. The electron beam starts from the top left-hand corner of the screen and moves horizontally from left to right. When it reaches the right-hand edge, it is switched off, moved back to the left side and down a fraction {this is the 'horizontal blank' period). It is then switched back on and the process repeated, until the beam reaches the bottom right-hand comer of the screen. At that point, it is switched off and brought back to the start position. Thus, the screen image is continually being redrawn (or 'refreshed') - 50 times per second in the UK PAL system. This is much too fast for the eye to follow and the image appears to us to be stable. However, some flicker does occur and may account for the eyestrain suffered by some people after long periods at their machine.

The picture is therefore built up from a stack of horizontal lines across the screen, these are usually termed 'scan lines'. The Atari can generate 262 scan lines, but not all of these are used in order to ensure the image appears on the screen of all makes of television. In fact, 192 scan lines are used to create the image. It is no coincidence that the maximum vertical resolution of the Atari is 192 (in Graphics 8-11 and Antic modes 12 and 14). In these modes, each horizontal row is one scan line high. The rows (or 'mode lines') of other graphics modes are composed of more than one scan line (e.g. one mode line of Graphics 0 is eight scan lines high). Table 1 shows how the mode lines of each graphics mode are made up, plus the resolution and memory requirements for each mode.

Table 1: The ATARI Graphics modes

BASIC

mode

ANTIC

mode

Resolution (max)

Colours

Scan lines/

mode lines

Bytes/

line

Memory

Type

0

2

40x24

1

8

40

960

T

-

3

40x19

1

10

40

760

T

12

4

40x24

5

8

40

960

T

13

5

40x12

5

16

40

480

T

1

6

20x24

5

8

20

480

T

2

7

20x12

5

16

20

240

T

3

8

40x24

4

8

10

240

G

4

9

80x48

2

2

10

480

G

5

10

80x48

4

4

20

960

G

6

11

160x96

2

2

20

1920

G

14

12

160x192

2

1

20

3840

G

7

13

160x96

4

2

40

3840

G

15

14

160x192

4

1

40

7680

G

8

15

320x192

1

1

40

7680

G

9-11

15

80x192

var.

1

40

7680

GTIA modes

Notes

1) GTIA modes have identical DLs to Graphics 8.

2) Total memory requirements shown are for full-screen modes (no text window) without any added unused bytes or for the DL. See ‘Mapping the ATARI’ pp. 17-21.

3) BASIC modes 12-15 are not available on the 400/800 series.

4) T = Text mode, G = Graphics mode.

The fundamental unit of horizontal measurement on the screen is the colour clock. This is actually a hardware limitation in that a colour clock is the length of the smallest possible dot on the screen whose colour can be controlled independently of adjacent dots. The Atari can display a screen 228 colour clocks wide, but only 160 of these are used on a normal screen to ensure the sides of the picture are not cut off on the television. (Although this produces a border at each side, at least the care taken by the Atari's designers ensures the machine will work with virtually any TV - unlike some inferior machines, which won't).

The machine can also light each half of a colour clock independently, producing a maximum horizontal resolution of 160 x 2 = 320 points, although this sacrifices additional colour for the reasons given above. Incidentally, a pixel (picture element) is the basic graphics unit which varies in size from one mode to another. In text modes, one pixel is usually taken to mean one character, although the individual dots making up each character are also sometimes called pixels - very confusing!

THE ANTIC CHIP

Discussion of TV screen displays is all very well but what has this to do with the display list? Well the TV display is under control of a separate microchip inside the Atari called Antic. Being a separate microprocessor, it needs a program to run it, which is in fact the purpose of the DL. The Display List is located in RAM, although its exact location depends on the graphics mode in use and the amount of memory installed in your machine. The Atari therefore has a pointer to the first byte of the DL at locations 560 and 561. The start of the DL is stored here in LSB/MSB format, so that in BASIC the start can be found by:

DL= PEEK(560)+256*PEEK(561)

Before we go on, take a look at Table 2. This contains some additional important memory locations I shall be referring to in this article.

Table 2: Summary of memory locations

Location

Name

Description

88, 89

SAVMSC

Location of the first byte of screen memory in low and high byte format (i.e. SCREENMEM=PEEK(88)+256*PEEK(89)). The first byte is displayed in the top left-hand corner of the screen.

87

DINDEX

Contains the current Graphics mode number (the BASIC/O.S. number, not the ANTIC number).

660, 661

TXTMSC

Identical to 88, 89, but for the text window memory area.

659

TINDEX

Identical to 87 for the text window.

560, 561

SDLSTL

Location of the first byte of the display list in low and high byte format. Change these locations to point to your own DL if you set up a new one elsewhere in memory.

512, 513

VDSLST

Location of the first byte of a DLI service routine in low and high byte format.

559

SDMCTL

Direct Memory Access Control. Controls playfield width and Player-missile graphics enabling. POKEing with zero turns off ANTIC; POKE with 34 (or press System Reset) to turn it back on with a standard width playfield and no PMG.

54276

HSCROL

Horizontal fine scroll register. Will fine scroll up to 16 colour clocks horizontally; bit four of the display list mode line instruction must be set to enable this register (add 16).

54277

VSCROL

Vertical fine scroll register; scrolls up to 16 sca lines vertically. Bit five of the DL mode line code must be set (add 32).

106

RAMTOP

Top of useable RAM (in pages) in the computer. Can be user-altered to reserve space for character sets, Player-missile graphics, etc. Initialised to 160 in a 48K system.

Listing 1

AtariLister - requires Java

At this point, type in and run Listing 1. I suggest you save this program, as it will allow you to examine the DL for any Graphics mode. The program will ask if you want a printout as well as screen display. Type the letter N if you don't have a printer. As an example, on being asked which mode type '1' and press RETURN. After a second or two, you should see something like this:

Display List for Graphics 1

112, 112, 112, 70, 128, 157, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 66, 96, 159, 2, 2, 2, 65, 94, 157

This is the DL for Graphics 1. Some of the numbers may be different in your machine. These are memory locations which depend on the amount of memory fitted in your computer. Let us now examine the meaning of the various numbers present in this DL.

The first three numbers are 112 (decimal). Each 112 is an instruction to Antic to leave eight blank scan lines, making a total of 24 blank lines at the top of the screen. No data can be displayed on these lines, which take the border colour as default.

Why put blank lines there at all? This is to prevent picture cut-off or 'overscan' at the top of the screen. To see this, press Break and then type in direct mode:

DL=PEEK(560)+256*PEEK(561): POKE DL,0: POKE DL+1,0: POKE DL+2,0

You will see the picture move up, and on some TVs the top may actually be cut off. What this means is that when designing your own DLs, you should always start with 24 blank lines. However, you can display less than 24 if absolutely necessary. Table 3 shows the instructions needed to display from one to eight blank lines.

Table 3: Blank line instructions

Instruction code Number of blank lines

0

1

16

2

32

3

48

4

64

5

80

6

96

7

112

8

You are not restricted to putting blank lines at the top of the screen. Listing 3 below shows how blanks can also be used in the middle of the DL. This program is explained more fully below.

The next number (70) is one of the most important in the DL. It is in fact made up of two instructions: 64 (Load Memory Scan) plus 6 (Graphics Mode 1 instruction - see Table 1). The LMS instruction is a very simple one in spite of its name, since its function is to tell Antic the location of the first byte of memory to be displayed on the screen. The LMS code should always be present added to the code for one mode line of one of the various graphics modes. If this is not done, blank scan lines will be displayed instead. In addition, the LMS code must always be followed by two bytes (128 and 157 in the above DL - this may vary in your machine). These two bytes are the location, in conventional low- and high-byte format of the start of display memory, and unless deliberately altered will be the same as in locations 88 and 89. By altering just these two bytes, you can cause your Atari to display the contents of any area of memory on the screen! Would you like to see what is happening in the very low RAM area? Type:

DL= PEEK(560)+ PEEK(561)*256: POKE DL+4,0: POKE DL+5,0

You are now looking at what is going on in Page 0 and succeeding Pages 1 to 3. If you wish, you can set an LMS instruction on every mode line, so that each line displays a different area of memory.

Following the LMS code and its two operand bytes, there are a series of 6' s. These are the Antic instruction codes for Graphics 1 (remember that Antic uses different code numbers to BASIC and the Operating System). If you count them, you will see that there are 19 '6' codes, which together with the one incorporated in the LMS code makes a total of 20 mode lines of Graphics 1.

Following these is another LMS instruction with a Graphics 0 code added. This directs Antic to a different memory area for the text window, which is of course in Graphics 0. The following two bytes are the start of the text window memory area and are followed by three lines of Graphics 0.

The final three bytes are an instruction to Antic to go back to the start of the DL and repeat the program over again. The code 65 means 'jump and wait for vertical blank', this is telling Antic not to start drawing the screen until the electron beam has returned to the top left-hand corner and the vertical blank period is over. The two bytes following the Jump instruction are the starting memory location for the DL itself, and are therefore the same as in locations 560 and 561. Your DL must always end with this instruction.

Simple arithmetic shows that we have 20 lines of Graphics 1 each eight scan lines high, and four lines of Graphics 0, also eight scan lines high. This makes a total of 20 x 8 + 4 x 8 = 192 scan lines. When designing your own DL, you should always approach this magic figure as closely as possible. Having less than 192 scan lines doesn't matter - you merely have a slightly smaller picture - but exceeding 192 does matter, since it may cause the picture to roll unpleasantly. If you must exceed 192, compensate by reducing the number of blank lines at the top - but remember that you may get picture cut-off as a result.

Now rerun Listing 1, and this time examine the DL for Graphics 8. You will see that as well as the LMS at the start of the DL and the one for the text window, there is a third in the middle of the DL. This must be present because of a limitation of Antic's memory counter, which cannot count past a 4K memory boundary. The practical meaning of this is that any Graphics mode displaying more than 4K of screen memory (e.g. Graphics 8-11) will need an additional LMS instruction in its display list in order to reset the memory counter and cross the 4K barrier.

There are three final instructions to consider, which don't appear in the 'built-in' DLs. These are:

128 call Display List Interrupt

16 horizontal fine scroll

32 vertical fine scroll

Any or all of these can be added to to any mode line (together with the LMS code if you wish). They are discussed more fully overleaf.

CUSTOM BUILT DISPLAY LISTS

There is no need for the Atari programmer to be restricted to the 'official' DLs and Graphics modes programmed into the Atari. By modifying the DL you can format the screen in virtually any way you wish. It is easiest to explain how this is done by means of examples.

Before we start I should point out that there are two ways of going about creating your customised DL. The first is to modify an existing DL, set up by a GRAPHICS statement, and the second is to create an entirely new one somewhere in a protected memory area. In general I would recommend the second approach, except for very small changes, since you can then bring your new DL into effect simply by changing the pointer at locations 560 and 561. Changing an existing DL may take a noticeable amount of time, and may be impossible if your new DL is longer than the existing one.

Example 1: Graphics 8 is fine in terms of resolution, but sadly lacking in colour. What is worse, the text window is in the same colour as the main part of the screen. However, we can improve this by changing the text window to Graphics 1, allowing four colour text. Listing 2 does this.

Listing 2

AtariLister - requires Java

This program is very straightforward, it finds the start of the Graphics 8 DL and then POKEs the appropriate locations with the Antic code for Graphics 1. Line 40 may need some explanation however. The Operating System thinks that the text window is in Graphics 0 - but Antic must now display it as Graphics 1. This is a potential conflict, since the 0.S. allocates 40 bytes per line for the text window, whilst Antic only uses 20 bytes per line. This would alter the position of text PRINTed in the window. We resolve this by telling the 0.S. that the window is now in Graphics 1 by POKEing location 659 with 1.

Example 2: I indicated earlier that it was possible to insert blank scan lines in the middle of a DL. This is demonstrated by Listing 3. This effect gives rather an attractive 'ruled page' appearance which could be useful in long text displays to break up the text (for example, in text adventures). Notice that the screen editor entirely ignores the blank lines - the cursor jumps from one mode line to the next. Unfortunately, putting in the blanks means that we can only put 21 Graphics 0 lines on the screen - this makes it difficult to use this screen for typing in a BASIC program for example (try it, and see what happens when you reach the bottom of the screen).

Listing 3

AtariLister - requires Java

However, this program also demonstrates how to set up a new DL from scratch. It must be placed in a suitable memory area - such as page six. Display lists are not relocatable due to the jump instruction at the end. The first three lines of the program READ the DATA for the new DL and POKE it into page six. Remember that zero is the code for one blank line and two is the code for Graphics 0. We must then allocate some memory space for the screen - in this case, done easily by the Graphics 0 call in line 70. We then need to know the starting memory location for the screen memory, which can be found from locations 88 and 89. These values are POKEd into the appropriate locations in page six. Space was reserved for these by the two zeroes following the LMS instruction (fourth number in line 50). If other LMS codes were present in our new DL we would of course have had to reserve space for the two bytes following each one. The final three bytes are the Jump instruction followed by the starting location of our new DL - the beginning of page six.

To bring our new DL into effect, we first turn off Antic by POKEing 559 with zero (you don't have to do this, but if you don't then the DL may be changed while Antic is 1 actually drawing a screen, making the picture jerk - which at best looks unprofessional). The DL pointer is then directed to our new DL in line 90 by POKEing 560 and 561 with the low and high bytes of the start of the new DL. Finally, Antic is turned back on again with a POKE 559,34. You can get out of the new DL by any GRAPHICS call. To get back again, simply repeat the steps in this last paragraph.

Example 3: The final example (Listing 4) is a little more complex, but nicely demonstrates a problem encountered when printing or drawing on a mixed-mode screen. Let us suppose that we want to design an attractive title page for a new game. We want to start off with giant text at the top of the screen, then decrease in size towards the middle, where we will print a message. The text will then enlarge again, and lastly there will be a text window for displaying messages and inputting replies. We'll call the program by some sort of dramatic name - say, ‘INVADERS', in honour of those little green men who started it all.

Type in Listing 4. Lines 10 to 90 should now be straightforward. Memory is assigned for our screen in line 70, and then the new, mixed-mode, DL is set up. The starting memory location for the text window is obtained from locations 660 and 661 (see Table 1). The method for plotting giant text in Graphics 4 comes from John Hulme in Page 6 issue 8.

Listing 4

AtariLister - requires Java

The real problem is, how do we PRINT or PLOT to the mixed graphics modes when the O.S. thinks we're in Graphics 0? There are two ways around this. The first is to treat each group of identical mode lines (or more generally, groups of lines with identical memory requirements) as a sort of graphics 'window'. For each window, we would then POKE the screen memory locations 88 and 89 with its starting memory location and to be on the safe side do a POSITION 0,0 to return the cursor to the top left-hand corner of the window. We then POKE 87 with the appropriate BASIC (not Antic) mode number and can now use the normal BASIC printing and drawing commands. Alternatively - especially for character graphics - we could calculate the offset from the start of screen memory and POKE the internal character codes (not the ATASCII codes) directly into the screen memory.

So much for the Display List itself. I suggest you experiment with the above examples and create your own DLs. In the next part of this article, I want to concentrate on some further applications of display list manipulation - the 'hidden' graphics modes, page flipping, the Display List Interrupt, and scrolling.

top