Chapter 8 : Using Colour
One of the major new features of the Archimedes is its provision of a palette of 4096 different colours. This provides an enormous choice/ particularly when compared with the six colours, plus black and white, available previously on the BBC micro. The further eight flashing colours cannot really be considered as genuinely different colours.
Of course, nothing is quite as good as it seems at first sight. The same is true of the use of colour on the Archimedes! You cannot display all 4096 colours on the screen at the same time, the maximum is 256. Furthermore, the decision by Acorn to maintain complete compatibility with the use of colour on the BBC Micro and Master series has led to additional complexity and confusion when it comes to dealing with the Archimedes.
There are two quite different approaches to the handling of colour on the Archimedes. First of all we shall look at those modes (0 to 7) used on the BBC micro, and all the other modes which allow a maximum of 16 colours on the screen at the same time. The 16 colours can be chosen to be any of the 4096 shades of colour which the Archimedes is capable of, and the methods of using and selecting these colours are similar to or an extension of those used in previous versions of BBC basic.
Modes 10,13 and 15 allow up to 256 colours to be displayed on the screen at any one time, but the method of selecting these colours is quite different to that used in the other modes. Furthermore, it is possible to choose these 256 colours to be any from the 4096 strong colour palette, but this does become quite complex, and you do not have the freedom to choose literally any colours from those available.
The same principles apply equally to 2, 4 and 16 colour modes, but where any examples are mode dependent, the commonly used mode 12 with a choice of 16 colours will be referred to. In each of these modes, the choice of colour in the first instance is referred to in terms of a logical colour. In mode 1, for example, these range from 0 to 3, in mode 12 from 0 to 15.
With each logical number is associated a physical colour, which is what we actually see on the screen. The corresponding default colour assignments are those which we have become accustomed to on the BBC micro (see Table 8.2).
At any instant of time, four colours will be active. These are the current foreground and background text colours, and the foreground and background graphics colours. With both text and graphics, the background colour is indicated by adding 128 to the logical colour number specified. This is done using colour for text and gcol for graphics. Thus, with the default colours in mode 12:
would select green for any subsequent text, while:
would select cyan as the new background text colour. Using COLOUR in this way determines the foreground and background colours for any text subsequently displayed on the screen. It does not change the colours of text already displayed.
The position is similar with graphics, but GCOL is used instead of colour. The CCOL instruction can have one or two arguments. If a single argument is specified then this is the logical colour number (ie, this becomes the current graphics colour). Therefore:
would select blue as the current drawing colour, while:
would select yellow as the new graphics background colour. Remember, particularly with graphics, that selecting a new background colour does not of itself change the colour of the background. A CLS or CLG command is needed to paint a new text or graphics background, and this, of course, wipes out anything already on the screen unless text or graphics windows have been set up first.
This form of the GCOL command is new to basic V. The old form, however, is equally valid, and specifies a plotting mode as well as a colour in the form:
GCOL <plot action> , <logical colour>
Note also, that basic v has added three further variations on the plotting action to those available previously. These are quite clearly documented in the User Guide, or basic Guide (post RISC OS), under the keyword GCOL.
Now that we know how to select a logical colour for text or graphics, we need to investigate how we can change the default assignment of colours and choose from the range of 4096 shades available. The principle is not new, and uses the VDU19 command to associate any physical colour with a specified logical colour. So, if we were to write:
VDU19,1,61 GCOL 1
logical colour 1 would become the current graphics colour, but the colour seen on the screen as a result would be cyan, and not the default red. This is because the vdu command has associated cyan (colour number 6) with logical colour 1. The syntax of this form of the VDU19 command is as follows:
VDU19,<logical colour>,<physical colour>|
Note the essential ' I' character at the end of the sequence. As an alternative to the use of VDU19, basic v allows the colour instruction to be used in a similar way:
COLOUR <logical colour>,<physical colour>
but without the terminating ' I' character. In this context, COLOUR has nothing to do with text colours alone. It is simply a way of linking a screen colour with a logical colour number.
One point which is important here is that any change of physical colour will affect not only any future graphics or text, but all instances of the logical colour already displayed on the screen. Changing the physical colour associated with the logical colour number used for the screen background will immediately change that background colour, but without affecting any other part of the display.
We have seen how to select a logical colour for text or graphics, and how to change the physical colour that is visible on the screen, but so far we have still been working within the 16 default colours shown in Table 8.2. How do we go about accessing the 4096 colours which the Archimedes is capable of displaying on the screen?
To do this we need to use a new variation on the VDU19 command, or the equivalent colour instruction. The syntax is:
In each case, '1' is the logical colour number (range 0 to 15 for mode 12), and 'r', 'g', and 'b' represent the proportions of red, green and blue to be mixed together to achieve the desired colour. Now although these values may theoretically range from 0 to 255, colour changes only occur in steps of 16. It is sometimes better to think of the two statements in the form:
The values of 'r', 'g' and 'b' should now be in the range 0 to 15. This means a range of 16 parts red, 16 parts green and 16 parts blue, giving the total of 4096 shades (16 * 16 * 16). Using either of the above instructions you can choose any of the 16 logical colour numbers (in 16 colour modes), and set it to be any of the 4096 colours.
It is quite impractical to list all the colours which are possible even if we could agree on the correct description of each shade. Therefore, there is a comprehensive program, which is listed at the end of this chapter, for mode 12 displays. This serves two separate purposes. To start with, the main part of the program is in the form of a procedure called PROCpalette, together with a number of other supporting procedures and functions.
The simplest way of using these procedures is to add just three lines to make a complete program (these are already included in the full listing), and run this:
100 MODE 12 110 PROCpalette(7) 120 END
The screen will show a rectangle containing the current palette. This is in the form of three small squares showing the intensities of red, green and blue, and a larger square showing the resulting mixed colour. The display also shows numerically the amounts of red, green and blue being used, in the range 0 to 15. The initial display shows brilliant white, that is determined by the '7' parameter above, made up of 16 parts red, 16 parts green and 16 parts blue.
The whole routine is mouse controlled. If you use the SELECT (left-hand) button and click on any of the three squares of red, green or blue, the intensity of the corresponding colour will be increased by one, and the composite colour will change as well, together with an updated numerical display. If you move the pointer to any position outside the display panel and click, the colour at the pointer position will be loaded into the display panel. Any subsequent changes to that colour in the panel display will be reflected wherever else it appears on the screen.
If you press the MENU (middle) button, the panel display will be replaced by a simple rectangle. Moving the mouse will move this rectangle around the screen. Pressing the MENU button again will re-display the panel in the new position. Lastly, pressing the ADJUST (right-hand) button at any time will exit from the procedure.
The routine may also be used to assist in the choice of colours in any other program. Simply append the procedures from line 1000 onwards to your program, and insert a call to PROCpalette at any suitable point. You can then experiment with your choice of colours while the display is on the screen. The routine allows the display panel to be moved around, so that you can use it while adjusting the colours in any part of your own screen display.
There are a few points to note. When PROCpalette is called, you need to specify an initial logical colour for the panel display. The routine itself sets its own palette for the logical colours 13,14 and 15. If you have used these in your own program you may find the resulting colours are changed. There is no way of avoiding this if the panel display is to show the correct proportions of red, green and blue in their true colours.
Pointer, Border and Flashing Colours
There are four further variations on the VDU19 command for mixing colours. The command:
determines the colour for a screen border. By default the border is always black, and therefore seldom obvious. Try using this version of the VDU19 command to see the effects which can be produced. The logical colour number is of no importance here - any value will do. For example:
will produce an orange-red coloured border.
The second variation of VDU19 can be used for changing the colours of the mouse pointer. It takes the form:
The default mouse pointer uses two colours, 1 and 2. If you try:
*POINTER VDU19,1,25,112,96,112 VDU19,2,25,240,80,160
you should see a pink pointer with a grey border. You can also define your own shape of pointer, and up to three logical colours (1, 2 and 3) may be used for this purpose. The pointer colours can also be changed using the instruction:
MOUSE COLOUR l,r,g,b
See Chapter Ten on the use of the mouse for more information on this subject.
Finally, VDU19 can also be used to set the red, green and blue proportions for flashing colours, thereby extending these to the 4096 colour palette.
The two commands are:
where the parameter '17' sets the first flash colour and '18' the second. The values 'r', 'g' and 'b' are the proportions of red, green and blue as before. The value of '1' determines which logical colour is to be set to a flashing colour pair.
Using the 256-colour modes
It is now time to look at the 256-colour modes, that is modes 10,13 and 15. The problem that arises from Acorn's decision to maintain compatibility in BASIC V with the colour control of previous versions of BBC BASIC is as follows. The colour of each pixel on the screen is stored as a byte of information in memory. Now, that would seem to be fine as one byte has a range from 0 to 255. However, a standard has already been established whereby the top bit of this byte is used to indicate whether the colour is a foreground or background colour. Setting the top bit by adding 128 to the colour number indicates a background colour. Maintaining that standard means that the remaining bits can offer a range of 0 to 128 at best. In practice not even this range is used and, as we shall see, the so-called 256- colour modes offer a choice of just 64 colours.
Using 64 Colours
In some ways, working with 64 colours is very similar to working with 16, 4 or 2 colours. The familiar instructions colour and GCOL are used to determine the current graphics or text colour, and 128 is added to this if we wish to specify a background colour. For example:
would produce pinkish-orange text, while:
would select a rather nice grey-blue for the graphics background. To increase the range of colours from 64 up to 256, a new keyword called TINT has been added to basic. In practice tint is used to add one of four levels of white to the base colour selected by COLOUR or GCOL, thus giving a range of 256 colours.
In fact, tint can take any value in the range 0 to 256, but only four distinct ranges are recognised:
TINT Level 0 1 2 3
When using TINT, keep to one set of four values, say 0, 64, 128 and 192. If no tint is specified then the default level of tint, which is zero, will always be applied. The result of this is that black, colour 0, really is black, but white, colour 63, is rather dull. To get the brightest possible white you will need to specify a tint of 192:
COLOUR 63 TINT 192
You should be aware, though, that if you use the highest level of TINT for this reason, then the same level of TINT applied to black will result in dark grey and not true black. You should also note that the last value of TINT specified will be applied to all subsequent COLOUR and GCOL statements in the absence of any alternative specification. In general, if you wish to use TINT, use it with every colour and GCOL statement to ensure you get the required result.
Alternatively, if the same level of TINT is to be used for several colour selections, then the keyword TINT may be used on its own to achieve this. For example:
would set the highest or lightest amount of TINT for the text foreground colour. Used in this way, the first parameter of TINT specifies which colour the TINT level is to be applied to - 0 = text foreground, 1 = text background, 2 = graphics foreground, 3 = graphics background. The second parameter is the level of TINT, as before.
TINT can also be used as a function to supplement point in order to determine the colour and tint of any pixel on the screen. POlNT(x,y) returns the logical colour number of the specified point, as before, while
TlNT(x.y) performs a similar function but returning the level of tint at the specified point (values 0, 64,128, or 192).
Although the default level of tint is zero, it appears that executing either *POINTER or MOUSE ON (to display the mouse pointer) has the unexpected side effect of setting the tint level to its maximum. This is an argument for getting familiar with TINT and including it in every COLOUR and GCOL statement you use.
You can use the following short program to see all 256 default colours displayed on the screen. The program works in text mode, displaying the word "COLOUR" in each shade in turn, but the same shades would apply for graphics. The BASIC colour numbers from 0 to 63 run in two columns down the screen with the colour number to the left. Each column repeats the word COLOUR four times, adding progressively more TINT from left to right. A REPEAT...UNTIL loop is used at the end of the program to maintain the finished display. Press ESCAPE to exit.
Listing 8.1 A display of 256 colours.
10 REM >Chap8-l 100 MODE 15 110 FOR col=0 TO 63 120 FOR tint=0 TO 192 STEP 64 130 COLOUR col TINT tint 140 x=-(col>31)*40:y=col+32*(col>31) 150 PRINTTAB(x,y) ; 160 IF tint=0 THEN PRINT SPC (-(col<l0) ) ; STR$ (col) ; 170 PRINTTAB(x+4+tint/8,y)"COLOUR"; 180 NEXT tint 190 IF col<>31 AND col<>63 THEN PRINT 200 NEXT col 210 REPEAT UNTIL FALSE 220 END
The program itself is fairly straightforward, but notice how the truth value of several comparisons (-1 or 0) is used to get the formatting correct. This is shown in line 140 in particular. This can be difficult to follow but is usually quite concise.
Understanding 256-Colour Modes
This chapter explains how to select any of the default 256 colours. These are, in effect, the equivalent of the logical colours we discussed with respect to other modes. However, redefining the colours to access all the 4096 shades of colour is another story altogether. To start with, it is useful to examine how the default colours are constituted.
As before, the default colours are made up from red, green and blue components, but this time a maximum of four parts of each only is allowed. This means the proportion of each colour is a number in the range 0 to 3. The actual colour number can then be computed according to the following formula:
colour number = 16*blue + 4*green + red
If we treat the COLOUR number as a byte, then the bottom two bits indicate the level of red, the next two the level of green, and the next two again the level of blue. The top-most bit, of course, determines whether the colour specified is to be used for the foreground or background. If we include the level of TINT, which we have already noted offers 4 levels also, then a COLOUR (or GCOL) statement can be expressed as:
COLOUR 16*blue+4*green+red TINT 64*tint
where each of blue, green, red and tint is in the range 0 to 3.
Redefining the Palette
Broadly, the way in which physical colours are linked to logical colour numbers, is through the use of a set of 16 palette registers. The register defines the actual colour to be used, while the logical colour number acts as an index to a palette register.
In those modes using 16 or fewer colours this all works beautifully as there is no problem in assigning one palette register to each logical number. By default the palette registers are set up with the colours as listed in Table 8.2. To display the correct colour at any point on the screen, which is constantly refreshed by information from the computer, the corresponding memory byte acts as an index to a palette register. The contents of the palette register control the output to the red, green and blue guns of the monitor. With 16 different levels to each of three colours - that makes four bits times three, making 12 bits in all.
The problem that arises in modes 10,13 and 15 is, of course, that we have only 16 registers to cope with the demands of 64 logical colours plus the four levels of TINT. The mechanism which is used is not simple, and attempting to change the palette in these modes can easily produce unexpected, and maybe undesirable, results.
In essence it works like this. The four levels of red, green and blue each supply two bits, which together with the four levels of TINT, again two bits, makes up a colour value of eight bits, which is stored in screen memory. From this, in conjunction with the palette registers, we need to form 12 bits to send to the monitor. The top four bits of the memory byte (1 bit red, 2 bits green, 1 bit blue) are sent directly to the screen D to A converters. The bottom four bits (range 0 to 15) form an index into a palette register which then supplies the remaining eight bits of colour information (3 bits red, 2 bits green, 3 bits blue).
The default palette settings in these modes have been carefully designed so that tint has the effect described, of adding one of four levels of white to any of 64 BASIC colours. If any of the palette settings are changed, this relationship is completely destroyed. Furthermore, changing a palette register definition affects not just one but sixteen of the BASIC colours. Redefining a palette register to change one colour to the desired subtle shade is likely to ensure that the other 15 colours affected change to shades that are less than useful. All of this is a recipe for potential disaster, and most programmers would do well to leave everything as it is. The default 256 colours have been carefully selected by Acorn to give a good range of colours.
The third program in this chapter demonstrates how to redefine the palette registers in order to display successively all of the Archimedes possible 4096 colours in a 256-colour mode (mode 15). The program displays the colours 16 at a time, each colour corresponding to the re- definition of a different palette register.
The 4096 colours can, in essence, be generated by cycling through 16 levels of red, green and blue, and three nested FOR...NEXT loops in the program do just that. Lines 220 to 240 determine the top four bits of the colour number (bit 3 blue, bits 2 and 3 green, and bit 3 red). These can then be combined to form (at line 250) a first approximation to the colour number for the following GCOL statement. This is further refined so that each level of blue cycled through specifies a different palette register. The contents of the corresponding palette register are set to the correct levels of red, green and blue by our old friend the VDU19 command at line 260. The last point to note is that the full specification of which palette register to use is determined partly by the GCOL number (bits 4 and 0) and partly by the shifted TINT value. Any previous concept of the latter's use as a TINT has quite disappeared.
Listing 8.2 Palette redefinition in 256 colour modes
10 REM >Chap8-2 100 MODE 15:OFF:ON ERROR MODE12:END 110 x=480:y=846:w=128:h=128 120 xl=0:yl=6:wl=7:hl=2 130 COLOUR 30 140 PRINTTAB(28,2)"4096 COLOURS in MODE 15" 150 PRINTTAB(26,3)"(using 16 palette registers)" 160 PRINTTAB (14,30)"Press SPACE BAR for the next 16-colour set;" 170 PRINTTAB(22,31)"Hold down SHIFT to jump 16 sets." 180 PRINTTAB(xl+9,yl)"Colour Set" 185 PRINTTAB(xl+9,yl+12)"GCOL/TINT" 190 FOR red%=0 TO 15 200 FOR green%=0 TO 15 210 FOR blue%=0 TO 15 220 blue3%=(bluet AND %1000)>>2 230 green23%=(green% AND %1100)>>2 240 red3%=(red% AND %1000)>>2 250 col%=(blue3%<<4) + (green23%<<2) + (red3%) 260 VDU19, bluet, 16, red%«4, green%«4,blue%«4 270 col%=col%-l*(blue%DIV4=l OR blue%DIV4=3)-16*(blue%DIV4=2 OR blue%DIV4=3) 280 tint%=(blue%MOD4)<<6 290 GCOL col% TINT tint's 300 RECTANGLEFILL (x+1.5*w*(blue%MOD4)),(y-1.5*h*(blue%DIV4)-h) ,w,h 310 PRINTTAB(x/16+1.5*w/16*(blue%MOD4)+2,32-y/32+(l,5*h* (blue%DIV4)+h+32)/32)"p";STR$(bluet) 320 PRINTTAB(xl+wl*(blue%MOD4),yl+hl*(blue%DIV4)+2)STR$(256*red% +16*green%+blue%);SPC3; 325 PRINTTAB(xl+wl*(blue%MOD4),yl+12+hl*(blue%DIV4)+2)STR$(col%);"/";STR$(tint%);SPC3 330 NEXT blue%:G=GET:IF INKEY-1 THEN red%-=red%<15 340 NEXT green%:NEXT red% 350 REPEAT UNTIL FALSE 360 END
You can cycle through all 4096 colours by pressing the space bar to control the display. The GCOL and TINT values for each colour are also shown on the screen. On a technical point, note the frequent use of the '>>>' and '<<' operators for multiplying and dividing by two, much the quickest way of achieving this. Thus the value after tint% at line 280 is given as (blue%MOD4)<<6 where the '<<6' is the same as multiplying by 2 a total of six times (ie, a value of 64).
As a final point, VDU19 can still be used as described for the other modes to change the pointer and screen border colours. They are selected by specifying the proportions of red, green and blue in the usual way.
While the large range of colours is certainly one of the major features of the Archimedes, the control and selection of colours is also more complex than hitherto. However, the potential is enormous and there must be a multitude of exciting visual effects just waiting to be discovered. All that is needed is a little imagination along with a good deal of time and effort.
Listing 8.3 Mode 12 palette display.
10 REM >Chap8-3 100 MODE12 110 PROCpalette(7) 120 END 130 : 1000 DEF PROCpalette(pixel) 1010 LOCAL x,y,z,bx,by,w,h,exit%,r,g,b 1020 w=256:h=224:exit%=FALSE 1030 r=15:g=15:b=15 1040 bx=512:by=384 1050 *POINTER 1060 MOUSE TO bx,by 1070 PROCselect_colour(0,0,bx,by,FALSE) 1080 PROCshow_palette(bx,by) 1090 REPEAT 1100 MOUSE x,y,z 1110 CASE z OF 1120 WHEN l:exit%=TRUE 1130 WHEN 2:PROCmove_palette(x,y,bx,by) 1140 WHEN 4:PROCpick(x,y,bx,by) 1150 ENDCASE 1160 TIME=0:REPEAT UNTIL TIME>8 1170 UNTIL exit% 1180 *SCHOOSE palette 1190 PLOT &ED,bx-4,by-8 1200 MOUSE OFF 1210 ENDPROC 1220 : 1230 DEF PROCshow_palette(x,y) 1240 MOVE x-4,y-8:MOVEx+w+4,y+h+8 1250 *SGET palette 1260 PROCset_colours 1270 PROCdraw_frame(x,y) 1280 PROCshow_colours(x,y) 1290 PROCwrite_text(x,y) 1300 PROCwrite_numbers(x,y) 1310 ENDPROC 1320 : 1330 DEF PROCdraw_frame(x,y) 1340 GCOL 12:RECTANGLE FILLx,y,w,h 1350 GCOL 7 1360 RECTANGLE x,y,w,h 1370 RECTANGLE x-4,y-8,w+8,h+16 1380 GCOL 0 1390 RECTANGLE x-2,y-4,w+4,h+8 1400 ENDPROC 1410 : 1420 DEF PROCshow_colours(x,y) 1430 LOCAL colour 1440 FOR colour=l TO 3 1450 GCOL colour+12 1460 RECTANGLE FILL x+1 6+80* (colour.-l) , y+h-104, 64, 64 1470 NEXT colour 1480 GCOL pixel 1490 RECTANGLE FILL x+16,y+16,w-32,64 1500 ENDPROC 1510 : 1520 DEF PROCwrite_text(x,y) 1530 GCOL 7:VDU5 1540 MOVE x+24,y+h-8:PRINT"Red" 1550 MOVE x+88,y+h-8:PRINT"Green" 1560 MOVE x+176,y+h-8:PRINT"Blue" 1570 VDU4 1580 ENDPROC 1590 : 1600 DEF PROCwrite_numbers(x,y) 1610 GCOL 12:RECTANGLE FILL x+16,y+80,224,32 1620 GCOL 7:VDU5 1630 MOVE x+30, y+112 :PRINT FNjustd-,2) 1640 MOVE x+110,y+112:PRINT FNjust(g,2) 1650 MOVE x+190,y+112:PRINT FNjust(b,2) 1660 VDU4 1670 ENDPROC 1680 : 1690 DEF FNjust(v,f) 1700 LOCAL v$:v$=STR$(v) 1710 =STRING$(f-LEM(v$)," ")+v 1720 : 1730 DEF PROCmove_palette(x,y,RETURN bx,RETURN by) 1740 LOCAL z,exit%:exit%=FALSE 1750 *SCHOOSE palette 1760 PLOT &ED,bx-4,by-8 1770 MOUSE TO x,y 1780 MOUSE RECTANGLE 4,8,1279-W-8,1023-h-16 1790 GCOL 3,6 1800 REPEAT:MOUSE x,y,z:UNTIL z=0 1810 REPEAT 1820 MOUSE x,y,z 1830 RECTANGLE x,y,w,h 1840 IF z=2 THEN 1850 RECTANGLE x,y,w,h 1860 PROCshow_palette(x,y) 1870 exit%=TRUE:bx=x:by=y 1880 REPEAT:MOUSE x,y,z:UNTIL z=0 1890 ELSE 1900 WAIT 1910 RECTANGLE x,y,w,h 1920 ENDIF 1930 UNTIL exit% 1940 MOUSE RECTANGLE 0,0,1279,1023 1950 ENDPROC 1960 : 1970 DEF FNarea(x,y,xl,yl,w,h)=(x>=xl AND x<=xl+w AND y>=yl AND y<=yl+h) 1980 : 1990 DEF PROCpick(x,y,bx,by) 2000 CASE TRUE OF 2010 WHEN NOT FNarea(x,y,bx,by,w,h):PROCselect_colour(x,y,bx,by,TRUE) 2020 WHEN FNarea(x,y,bx+16,by+h-112,64,64):PROCchange_colour(r) 2030 WHEN FNarea(x,y,bx+96,by+h-112,64,64):PROCchange_colour(g) 2040 WHEN FNarea(x,y,bx+176,by+h-112,64,64):PROCchange_colour(b) 2050 ENDCASE 2060 PROCupdate_palette 2070 ENDPROC 2080 : 2090 DEF PROCselect_colour(x,y,bx,by,flag%) 2100 LOCAL pl,p2 2110 IF flag% THEN pixel=POINT(x,y) 2120 SYS "OS_ReadPalette",pixel,16 TO ,,pl,p2 2130 r=pl>>>12 AND &FF 2140 g=pl>>>20 AND &FF 2150 b=pl>>>28 2160 IF flag% PROCshow_colours(bx,by) 2170 ENDPROC 2180 : 2190 DEF PROCchange_colour(RETURN c) 2200 c=(c+l)MOD16 2210 ENDPROC 2220 : 2230 DEF PROCset_colours 2240 COLOUR 13,16*r,0,0 2250 COLOUR 14,0,16*g,0 2260 COLOUR 15,0,0,16*b 2270 COLOUR pixel,16*r,16*g,16*b 2280 COLOUR 12,0,0,0 2290 ENDPROC 2300 : 2310 DEF PROCupdate_palette 2320 PROCset_colours 2330 PROCwrite_numbers(bx,by) 2340 ENDPROC