ROM Computer Magazine Archive ROM MAGAZINE ISSUE 3 — DECEMBER 1983/JANUARY 1984 / PAGE 6

Display List Interrupts - Part II
Using Player/Missile Graphics
by Bob Cockroft

    Display list interrupts allow the computer to have multi-colored players and missiles. Rising above the limitations of basic programming one is able to make far more interesting objects through different colors. The possibilities become almost endless for the (artistry) created by this technique.
    The display list is a program in the computer that is used by the Antic chip to display the screen. Despite varying slightly with each graphic mode, the display list basic format remains constant. The display list's base (or lowest) address can be determined by its location pointers (560,561 dec.) in the following manner,

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

    The first 3 bytes of the display list, places 24 blank lines at the top of the screen. The next 3 bytes(LMS) give the beginning address of where the screen data is located. Following this is a string of uniform bytes. This string of bytes is know as the instruction register(IR) mode bytes. Each byte controls the graphic mode of one horizontal line on the screen. By controlling each horizontal line of graphics, starting from the top to the bottom, there is a opportunity for extra color creation. The (IR) mode bytes change in value with each particular graphic mode. The table below gives the possible (IR) mode byte values and the corresponding graphic mode:

Table 1

graphic mode    Value in (IR) mode byte
 0         2
  1         6
  2         7
  3         8
  4         9
  5         10
  6         11
  7         13
  8         15

    In this second article in a series on display list interrupts, I will present a program that creates (multi) colored players or missiles. Displaying player(0) as a long vertical line, I will divide it with a color into sections. It is important to note with display list interrupts one can only print color in horizontal rows, As you will notice with the first program, one cannot color only a section of a horizontal line of player(0) data. Only a complete line of a player or missile can be colored.
    There are four steps to create a display list interrupt. First the color for the highest(highest on the screen) part on the player must be set. This can be done by poking a value into the color shadow register for the player(see table two), For example, for player(0) this location would be 704 dec.
    Second, one must determine where vertically to change the color. Remembering that each (IR) mode byte represents one line of graphics from top to bottom, one can find his desired dividing point by counting the number of graphic lines that is above this location. Then, located this (IR) mode byte in the display list. To indicate to the Antic chip that this is the place where you wish the interrupt to take place, add 128 to the byte. For example, if the dividing point were to be in the middle of the screen, the programmer would need to add 128 to the middle (IR) mode byte.
    As you may already know color controls are operated by two types of registers; hardware and shadow registers. Hardware registers are 'write only' locations. In other words, one can only poke these locations not peek 'at' them. Hardware registers are updated by the value in their corresponding shadow register everytime the Antic draws a screen. Each hardware register has a corresponding shadow registers. These registers are both 'read' and 'write' locations, in other words operate in the manner most memory locations do. Below is a table or hardware and shadow registers that are relevant to player./missile color.

Table 2

Player Hardware Shadow
       Register Register

player(0) 53266    704

player(1) 53267    705
player(2) 53268    706
player(3) 53269    707

    In other words every time the Antic draws a screen, the hardware register is updated with the value stored in its corresponding shadow register. The value stored in the hardware register is used to create a player's color. The following machine-language subroutine interrupts the process mentioned above. As the Antic moves down the display list it will be interrupted and forced to go to the machine code. Here the hardware register is changed during the process of creating a screen, before the hardware register can be updated by its corresponding shadow register. In other words, we have changed the color before the Antic has completed drawing the screen. The result is one player with two colors that meets at the pointer where the modified (IR) mode byte is.

Machine Language Subroutine

Mem.Loc Value Assembly ;Comment
1536 72  PHA ;PUSH 'A' ON THE STACK
1537 169 LDA ;LOAD 'A'
1538 1   #1  ;WITH ANY NO.
1539 141 STA ;AVOID CHANGE
1540 10  $0A ;IN MIDDLE OF LINE
1541 212 $D4
1542 169 LDA ;LOAD 'A'
1543 50  #50 ;WITH NEW COLOR
1544 141 STA ;STORE NEW COL.
1545 18  $12 ;IN HARDWARE
1546 208 $D0 ;REGISTER
1547 104 PLA ;REPLACE 'A'
1548 64  RTS ;RETURN

    The next thing we need to do is to tell the Antic where to go during the interrupt. As the Antic moves down the display list it will come to the byte that has been modified to force a interrupt.(IR mode byte+128 remember'') When this happens the Antic will look at the interrupt pointers to see where it is to go. Our destination is the machine-language subroutine above. Therefore we poke the location of the code into these addresses. It is important to realize that the location store in the pointer(512,51 3) is in LSB/MSB form.(Therefore 1536 decimal would be '0' and '6'; see below)

    1536/256=6
    Therefore:
    POKE 512,0:POKE 513,6

    The last step would be to enable a non-maskable interrupt.(NMI) This can be done by POKEing 54286 dec. with 192
    Program 1 contains all the steps I have mentioned. After successfully typing and RUNning it, you will see player(0) as a long vertical line which is divided by two colors. Use the joystick to change the colors and move the point of division.
    Program 2 is practical application of what you have read. It consists of a red man, created by player(0), which has a black hat. This is perhaps not the most interesting program you have ever seen. However, it should shoe you what is possible, and could help you get started.

    The third thing we need to do is to create a machine language subroutine which the Antic chip is to go to during the interrupt.

90 REM *
92 REM *MULTIPLE COLORED PLAYER/MISSIE *
94 REM * PROGRAM 1
96 REM *
99 REM *LOAD IN THE MACHINE SUBROUTINE
100 FOR X=1536 TO 1536+12
115 READ D
120 POKE X,D
130 NEXT X
122 V=50
135 REM LOAD LOCATION FOR THE INTERRUPTS JUMP
140 POKE 512,0
150 POKE 513,6
195 REM * SET UP MISSILE GRAPHICS
200 GRAPHICS 8
210 POKE 559,62
220 POKE 53248,120
230 POKE 704,88
240 I=PEEK(106)-8
250 POKE 54279,I
260 POKE 53277,3
270 J=I*256+1024
275 REM * DRAW PLAYER(0) AS A LONG LINE
280 FOR X=1 TO 255:POKE J+X,255:NEXT X
290 DL=PEEK(560)+256*PEEK(561)
292 POKE 54286,192
295 REM * ADD 128 TO INTERRUPT BYTE
299 POKE DL-1+V,15
300 POKE DL+V,15+128
301 POKE DL+1+V,15
302 POKE DL+99,79:POKE DL+100,0:POKE DL+101,144
305 REM * ENABLE (NMI)
320 REM * CHANGE THE VALUE PLACED IN THE HARDWARE REGISTER
330 IF STICK(0)=l1 AND P<:=255 THEN P=P+l
340 IF STICK(0)=7 AND P>9 THEN P=P-1
342 IF STICK(0)=14 AND V>0 THEN V=V-1
344 IF STICK(0)=l3 AND V<150 THEN V=V+l
350 POKE 1543,P
390 ? "COLOR NO. :1";P;° VERTICAL POS :";V;"  "
400 GOTO 299
499 REM * MACHINE CODE DATA *
500 DATA 72,169,1,141,10,212,169
510 DATA 12,141,18,208,104,64

50 REM *
60 REM *MULTIFLE COLORED PLAYER/MISSILE *
64 REM * PROGRAM 2
66 REM *
80 REM * LOAD IN THE MACHINE SUBROUTINE
100 FOR X=15136 T0 1536+12
115 READ D
120 POKE X,D
130 NEXT X
135 REM LOAD LOCATION FOR THE INTERRUPTS JUMP
140 POKE 512,0
150 POKE 513,6
195 REM * SET UP MISSILE GRAPHICS
200 GRAPHICS 8
205 DL=PEEK(560)+256*PEEK(561)
210 POKE 559,62
220 POKE 53248,120
230 POKE 704,65
240 I=PEEK(106)-8
250 POKE 54279,I
260 POKE 53277,3
270 J=I*256+1024
275 REM * DRAW THE PLAYER(0)
280 FOR X=1 TO 17
282 READ D
284 POKE J+90+X,D
286 NEXT X
290 POKE DL+68,15+128
292 POKE 1543,88
900 POKE 54286,192
999 REM * MACHINE CODE DATA
1000 DATA 72,169,1,141,10,212,169
1010 DATA 12,141,18,208,104,64
1015 REM * DATA TO DRAW PLAYER(0)
1020 DATA 28,28,28,28,127,28,20,28,8,127,93,28,28,28,20,20,54