ROM Computer Magazine Archive ROM MAGAZINE ISSUE 6 — JUNE/JULY 1984 / PAGE 32

MULTICOLOURED
CHARACTER GRAPHICS
by Bob Cockroft

    It is assumed that the reader of this article has a basic knowledge of both GR.0 character graphics and Display Lists.
    Although many people know how to use redefined character sets to improve graphic displays, many still do not know how to create multicoloured characters in (IR) mode 4 and 5 graphic screens. This is unfortunate in that many programs can be greatly improved with a little colour. As many as four colours can be drawn simultaneously on one character. There are two methods of doing this.
    The first method, using the GR.0 characters, is simple. By creating a duplicate of the ROM character set in RAM and adjusting Character Base Register so that it points to that new set, one is able to modify the character by changing their bit map structure. In addition, colour character graphics give higher resolution and uses less memory than any of the high resolution graphic modes.(For a complete description of creating GR.0 character graphics refer to the article in ROM issue number 4 called `Character Graphics Made Easy'). It is possible to get multicoloured characters by artifacting the GR.0 character set. By lighting up every other pixel in the character, a colour T.V. will draw a block of colour that is different from other characters which are not artifacted. By lighting up bits differently for each horizontal line, a number of blocks of colour can be created(see below)

bits set for block of color

    The reason artifacting works for the GR.0 character set is that each pixel is the same size as the pixels in a GR.8 screen. As an result, any method of artifacting in GR.8 will also work for characters in GR.0 However, this technique of creating multicoloured characters is not without some major disadvantages. Because artifacting(ploting every other pixel) needs to be done in order to get different colours, the horizontal resolution is reduced by one half. In addition, one is not able to control the colour the computer is to display by using the COLOR REGISTERs. The colour displayed in a refined GR.0 character set is determined primarily on the background colour. If you are one who does not mind these disadvantages, then GR.0 character sets are probably best for you. However, for those who want more, there is a better method of getting multicolours.
    The second method artifacts two character sets that are multicoloured, high resolution and react to the values in the Color Registers. These sets are not widely known, probably due to the fact that they are not accessible through the BASIC command "GRAPHICS". They lie between and have many of the same characteristics of GR.0 and GR. 1. The computer, every time a GRAPHICS command is made, produces a series of Instructions called the Display List. This list tells the Antic chip how to display screen data. Seen as a series of identical values, the Instruction Register (IR) numbers tell the Antic chip which graphic mode to present on the screen. Varying with the screen, each possible value of the (IR) mode numbers represents a different graphic mode. For example, the (IR) mode number for GR.0 is `2' where as the (IR) mode number for GR. 1 on is `6 '. Below is a program that presents the Display List of any graphic mode that can be called from BASIC. RUN the program and type-in the number of the graphic mode you want to examine. Remember that the series of identical numbers in the center of the list are the (IR) mode numbers for graphic mode for which you asked. Examine the (IR) mode numbers for the different graphic modes. Table 1 gives the 9 graphic modes and the corresponding (IR) mode number.

1 REM * PRINT DISPLAY LIST
5 DIM DAT(200)
10 B=175
12 GRAPHICS 0
14 ?:? "Which graphic mode?"
17 INPUT A
20 GRAPHICS A
25 TRAP 20
30 DL=PEEK(560)+256*PEEK(561)
40 C=1
50 DAT(C)=PEEK(DL=-1):C=+1
60 IF C<B+1 THEN 50
70 GRAPHICS 0
80 L=1
90 ? DAT(L);" ";
100 IF L>13 THEN 130
110 L=L+1
120 GOTO 90
130 GOTO 14



Table 1
 
  GRAPHICS `X'
 (IR) mode number   
0

2

(IR) modes 3,4 and 5
1

6
2

7
3

8
4

9
5

10
6

11
7

13
8

15


    The graphic modes between GR.0 and GR. 1, in other words (IR) modes 3,4 and 5 are the ones we are interested in. Although they are not accessible from BASIC, they offer some unique opportunities for colour manipulation. (IR) mode 3 is nearly the same as GR.0 and as a result not overly useful for our purposes. However, (IR) mode 4 and 5, although somewhat different from one other, are both able to produce multicolours. (IR) mode 5 characters have the same horizontal length as GR.0 characters, but are twice as tall. As a result, any character that needs to be taller than normal characters should be created with this mode. On the other hand, (IR) mode 4 characters are the same size as GR.0 characters in all respects. This fact enables a screen to be easily created to have both the normal GR.0 characters and the modified and multicoloured (IR) mode 4 characters. This is important because a ROM character, as seen on an (IR) mode 4 screen, is nearly unreadable. As a result SCOREs or any other readable portions of games should be written on GR.0,1 or 2 screens.
    The first thing to do to make a multicoloured graphics mode is to create a graphics mode 0 screen.

1    GRAPHICS 0

    Secondly, determine where the display list starts by examining the values in the Display List Pointers.

2    D = PEEK(560) + 256*PEEK(561)

    Thirdly, add the value of the (IR) mode(4 or 5) you want to create to the LMS instruction.

3    POKE D+3,64+4

    Finally, change the (IR) mode number for GR.0 (2's) into the (IR) mode number for the wanted multicolour mode (4's or 5's)

4    FOR X = 6 TO 28:POKE D + 6 + X,4:NEXT X


    If you are still confused, reread the four steps while examining the Display List below.

Graphics 0 Display List

D     12  These 3 values of `112'
D+1   112 print a total of 24 blank
D+2   112 lines on top of the screen
D+3   66  LMS 64+(IR) mode number for GR.0 2=66 For Antic mode 4 change this value to 68(64=4)
D+4   64  These 2 values give the
D+5   156 address of the first byte of data
D+6   2   The `2's or (IR) mode lines represent horizontal lines of GR.0
D+7   2   change the `2's into the (IR) mode number
D+8   2   of the wanted (IR) mode
D+9   2   For example, 4 or 5
D+10  2
D+11  2
D+12  2
D+13  2
D+14  2
D+15  2   The higher the resolution of
D+16  2   the graphics mode, the more
D+17  2   (IR) mode number will there
D+18  2   be.

D+19  2
D+20  2   Each (IR) mode number represents
D+21  2   one horizontal line on the screen
D+22  2   called a scan line.
D+23  2   Higher resolution requires a large
D+24  2   number of scan lines to provide
D+25  2   detail
D+26  2
D+27  2
D+28  65  Jump and wait for vertical blank
D+29  32  The address of the
D+30  156 Display List

    There is no reason to change the last three bytes of the GR.0 display list when changing it to (IR) mode 4, because the width of both of their mode lines are identical. In other words, both GR.0 and (IR) mode 4 lines both use 8 scan lines each. However, because (IR) mode 5 lines are twice as tall, fewer mode lines are put on the screen. The result of this is that an (IR) mode 5 display list will be shorter. The values in the last three bytes which tell the computer to redraw the screen, will need to be moved to a new memory location. It is important that the total of all scan lines on the screen add up to 192. Each (IR) mode 5 line uses 16 scan lines. Therefore, not more than (1921/86) = 12 (IR) mode 5 lines can be placed on the screen at once.

(It may be helpful to refer to table 2 while reading the next paragraph)

    The location for the colour you wish to display is determined by the placement of lit pixels. The 8 by 8 character block is divided into 4 columns of 2 pixels each. It is the arrangement of these 2 pixels that determines which COLOR REGISTER responds to these pixels position. When the right pixel is lit, COLOR REGISTER 0 controls the colour for the two pixels. When the left pixel is lit, COLOR REGISTER 1 controls the colour for the two pixels. When both pixels are lit, COLOR REGISTER 2 controls the colour for the two pixels. And when neither pixel is lit, the background color (COLOR REGISTER 4), controls the colour for the two pixels. It is important to note that it is also possible to have more than one colour on one horizontal line of a character. In fact, one can have as many as four. (refer to the last horizontal row in Table 2)

colors in horizontal line

Table 2

Right Pixel=COLOR REGISTER 0

Left Pixel=COLOR REGISTER 1

Both Pixels=COLOR REGISTER 2

Neither Pixels=Background COLOR

Mix: left side=COLOR 1
:right side=COLOR 2

Mix: left side=COLOR 0

right side=background COLOR

Four colour on one horizontal line

    Note: the first two pixels respond to COLOR 0, the second two respond to COLOR 1, the third two respond to COLOR 2: the last two respond to COLOR 2

    It is difficult to create both the wanted character shape and the colour patterns. A good deal of experimentation is needed before most programmers get a redefined character that they are satisfied with. Because of this, I have made a multicolour character editor to go with this article. Although it does not have some extra features that many commercial editors do, it should be helpful in speeding up the character redefining process. The editor is quick and easy to use. After you have typed it in and RUN it, the program will immediately create a duplicate ROM character set in the RAM. In order to do this quickly, I used a short machine language subroutine. Next, use the joystick to change the hue of the colour square to a shade you like. Press the START button in order to register your choice with the computer. Repeat this process for the 3 COLOR REGISTERS which the program allows you to change. The background COLOR is maintained a constant black so that the modified character is more distinctive. After this the screen will become dark and ask you to draw your character with the joystick in the enlarged character block. To erase, press the joystick button and move the cursor over the pixel you want clear. Press the START button when you want to see the modified character in real size. If you are satisfied with what you see, press the SELECT button to end the editing session. Otherwise, press OPTION and continue to draw with the joystick. Some brighter colour combinations may cause the instructions at the bottom of this screen to become unreadable. Just follow the written instructions above, or first experiment with darker colours and you should have no problems. After ending your editing session, the program will display a line of 8 numbers. These numbers are values that must be inserted into the character set in order to modify your character. In addition, the values for the COLOR REGISTER that you chose at the beginning of the program are displayed. With this information, you will be able to easily add this new character to your programs. Press the RESET button before restarting the editor to update the character pointers.
    The second program is an example, of what can be done with character graphics. It creates a display depicting a colourful space scene. Multicoloured stars, spaceships and a station covered in graffiti are all possible with character graphics. This program uses all the same processes described in this article. All items have been created with the help of the character editor.


2 REM * PROGRAM 1
3 REM * MULTIPLE COLOUR
4 REM
5 REM * CHARACTER EDITOR
10 GRAPHICS 0
11 SETCOLOR 2,16,1
12 POKE 559,62
13 POKE 53248,120
15 T=PEEK(106)-16
16 POKE 54279,T
17 POKE 53277,3
18 BAS=T*256+1024
20 FOR X=150 TO 180:POKE BAS+X-1,255:NEXT X
21 CR=0
22 POKE 752,1
24 POSITION 15,6:? "SETCOLOR ";CR
25 POSITION 3,9:? "Use joystick to determine value for COLOR REGISTER ";CR
26 POSITION 8,12:? "Press START button to end"
30 X=88
31 ST=STICK(0)
32 IF ST=14 THEN X=X+1
33 IF ST=13 THEN X=X-1
34 POSITION 12,16:? X;" "
35 IF X>255 THEN X=255
36 IF X<0 THEN X=0
37 POKE 704,X
38 IF PEEK(53279)<>6 THEN 31
40 CR=CR+1
42 IF CR=1 THEN X8=X
43 IF CR=2 THEN X9=X
44 IF CR=3 THEN X10=X
45 FOR Y=1 TO 75:NEXT Y
48 IF CR<3 THEN 24
50 POKE 752,0
60 DIM CH(8)
70 RT=PEEK(106)-4
80 NT=RT*256
90 POKE 106,PEEK(106)-5
99 REM * LOAD MACINE CODE
100 FOR X=1 TO 31:READ D:POKE 1535+X,D:NEXT X
108 REM * MOVE CHARACTER SET
110 X=USR(1536)
120 FOR X=1 TO 8:CH(X)=0:NEXT X
130 REM * EDIT SECTION
139 POKE 53248,0
140 GRAPHICS 4:COLOR 1:POKE 708,X8:POKE 709,X9:POKE 710,X10:POKE 752,1
150 DL=PEEK(560)+256*PEEK(561)
160 XP=40:YP=13
165 REM * DRAW SHAPE
169 ? ,,"Z":? :? "Press START to display character"
170 ST=STICK(0)
180 IF ST=14 AND YP>13 THEN YP=YP-1
190 IF ST=13 AND YP<20 THEN YP=YP+1
200 IF ST=7 AND XP<47 THEN XP=XP+1
210 IF ST=11 AND XP>40 THEN XP=XP-1
220 IF STRIG(0)=1 THEN COLOR 1:FOR X=1 TO 5:NEXT X:GOTO 250
230 FOR X=1 TO 5:PLOT XP,YP:NEXT X
240 COLOR 0
250 PLOT XP,YP
260 IF PEEK(53279)=6 THEN 280
270 GOTO 170
280 SB=PEEK(88)+256*PEEK(89)
282 POKE 708,X8
284 POKE 709,X9
286 POKE 710,X10
290 SBH=SB+135
300 FOR X=0 TO 7
310 CH(X+1)=PEEK(SBH+X*10)
320 POKE NT+464+X,CH(X+1)
330 NEXT X
340 POKE DL+45,68
350 POKE DL+48,4:POKE DL+49,2:POKE DL+50,2
360 POKE 756,NT/256
370 POKE 752,1:? „"Z":? :? "OPTION to draw/or/SELECT to continue"
380 IF PEEK(53279)=3 THEN 169
390 IF PEEK(53279)=5 THEN 410
400 GOTO 380
410 GRAPHICS 0
420 POKE 752,0
430 REM * PRINT OUT DATA
440 SET=NT+464
450 FOR W2=0 TO 7:POKE SET+W2,CH(W2+1):NEXT W2
460 GRAPHICS 0:POSITION 2,5:? "Press the character you have modified"
470 ? :? "         Character data below"
480 ? :POSITION 6,9:FOR X=1 TO 8
490 IF X=8 THEN ? CH(X):GOTO 520
500 ? CH(X);",";
510 NEXT X
520 POKE 756,NT/256:?
521 ? :? "          COLOR REGISTERS"
522 ? :? "loc 708=";PEEK(708);"loc 709=";PEEK(709);" loc 710=";PEEK(710)
530 ? :? "Press the RESET button before       reRUNning the editor or you will get bad data"
532 ? :? "Your modified character: Z"
540 DATA 104,160,0,162,0,189,0,224,157,0,156,232,224,0,208,245,200,238,7,6,238,10,6,192
550 DATA 5,208,232,96,0,0,0

1 REM * CHECK DATA *

2 DATA 8365,220,724,541,714,957,226,932,75,107,20,985,92,756,544,873,230,369
26 DATA 8709,629,547,26,488,490,597,444,227,915,752,738,383,386,428,587,199,873
60 DATA 7277,815,139,879,445,699,901,938,20,50,528,33,435,843,55,380,39,78
180 DATA 7442,310,304,257,298,823,364,800,70,790,837,766,25,29,63,969,76,661
320 DATA 10816,609,776,119,623,247,821,796,788,835,9,922,663,999,979,650,866,114
490 DATA 4683,48,969,776,398,86,512,782,106,474,532


Assembler Listing

00010  .LI OFF    ;MOVE CHARACTER SET
00020  .OR $600
00030  .TA $2600
00040  .TF "D:AD4.OBJ"
00100 BEGIN PLA
00108  LDY #0
00110 L2 LDX #0
00120 L1 LDA $E000,   ;OLD LOCATION
00130  STA $9000,X    ;NEW LOCATION
00140  INX
00150  CPX #0
00160  BNE L1
00170  INY
00172  INC $607
00174  INC $60A
00180  CPY #5
00190  BNE L2
00200  RTS


5 REM * PROGRAM 2
10 REM * SPACE DISPLAY
100 T=PEEK(106)-4
105 NT=T*256
110 POKE 106,PEEK(106)-5
120 GRAPHICS 0
130 POKE 708,40:POKE 709,202:POKE
710,148
140 FOR X=0 TO 1023:POKE NT+X,PEEK(57344+X):NEXT X
150 FOR X1=1 TO 14
160 READ LOC
170 SET=NT+LOC*8
180 FOR X2=0 TO 7:READ D
190 POKE SET+X2,D
200 NEXT X2
210 NEXT X1
220 POKE 756,NT/256
230 SETCOLOR 2,16,1
240 POKE 752,1
300 POSITION 10,10:? "&";""';"#";"$";"/";"%"
305 POSITION 25,10:?
310 POSITION 29,9:? "/";"/":POSITION 29,11:? "/";"/"
315 POSITION 29,8:? "*";"*"
320 POSITION 29,12:? "*";"*"
325 POSITION 29,7:? "!";"!"
330 POSITION 29,13:? "!";"!"
340 POSITION 29,11:? "/";"/"
350 POSITION 10,7:? "$":POSITION 15,14:? "$"
360 POSITION 15,4:? ",";"!";"'";"'";"!";"-"
370 POSITION 35,4:? "$":POKE 5,20:? "$"
375 POSITION 5,21:? "!":POSITION 5,20:? "+"
380 POSITION 5,5:? "(":POSITION 13,12:? "("
385 POSITION 38,3:? "(":POSITION 37,19:? "("
390 POSITION 18,18:? "(":POSITION 2,20:? "("
395 POSITION 5,18:? ")":POSITION 15,15:? ")":POSITION 15,3:? ")":POSITION 12,2:? ")"
400 POSITION 24,19:? ")":POSITION 37,15:? ")":POSITION 12,12:? ")":POSITION 15,18:? ")"
405 POSITION 5,10:? ")":POSITION 4,8:? ")":POSITION 30,3:? ")":POSITION 28,4:? ")"
410 POSITION 18,10:? ")":POSITION 27,18:? ")":POSITION 31,20:? ")":POSITION 33,17:? ")"
415 POSITION 26,14:? ")":POSITION 37,10:? ")"
420 POSITION 4,15:? "a":POSITION 32,22:? "a":POSITION 20,21:? "a":POSITION 7,22:? "a"
425 POSITION 25,3:? "a"
460 GOTO 460
500 DATA 1,60,255,165,165,165,165,255,60
520 DATA 3,165,165,165,165,255,255,255,255
530 DATA 4,129,129,129,165,189,165,129,129
540 DATA 5,0,128,208,213,213,213,208,128
550 DATA 6,1,3,131,235,235,131,3,1
560 DATA 7,170,170,170,255,255,255,85,85
570 DATA 8,21,32,80,136,104,16,32,128
580 DATA 9,0,0,0,0,32,48,32,0
590 DATA 97,0,8,12,62,12,8,0,0
600 DATA 10,255,195,165,153,153,165,195,255
610 DATA 11,8,8,62,8,8,8,28,62
620 DATA 12,1,35,35,255,35,35,1,0
630 DATA 13,128,132,196,255,196,132,128,0
640 DATA 15,181,181,181,215,215,223,90,90

1 REM * CHECK DATA
5 DATA 7189,298,622,99,843,486,7,464,216,175,876,161,574,205,822,822,242,277
240 DATA 8611,923,321,25,56,640,679,622,663,690,676,288,304,635,637,707,691,54
400 DATA 7479,198,948,194,741,310,519,840,191,303,311,175,867,205,31,617,681,348
610 DATA 1994,696,822,240,23637,707,691,54