Mandelbrot

By Mark Bellis

Originally published in EUG #29

Files required:

File: Format: Brief description:
16C1SRC 6502 M/C Source code for 16-colour mode 1
SHVGEN BASIC Mandelbrot generator for 16 colour "Sea-horse valley" picture files U.SHVPIC1 and U.SHVPIC2
SHVPIC1 SCREEN 4-colour Mandelbrot picture of "Sea-horse valley"
SHVPIC2 SCREEN Used with SHVPIC1 to give the 16 colour picture
SHVLOAD BASIC Loader for 16 colour "Sea-horse valley" picture
MBGEN BASIC Mandelbrot generator for 4 colour mode 1 (for all machines, so even people without shadow RAM can plot mandelbrots)

All of these files are stored in a separate directory, M. To see what the Mandelbrot programs can produce, go into this directory then either:

    CHAIN"M.SHVLOAD" (on machines with Shadow RAM)
or:
    MODE 1
    *LOAD M.SHVPIC1 3000
SHVPIC2 is closely related to SHVPIC1: Each picture is a 4-colour Mode 1 picture, and SHVLOAD uses both together (one in main RAM and the other in shadow RAM) to produce the 16-colour picture. Please be warned if you are a Shadow RAM machine owner who is allergic to strobes that the 16-colour effect is rather flickery due to the screen refresh effectively being at 25Hz instead of 50Hz.

There follows an explanation of how the mandelbrot programs work:

10-20 ... Both mandelbrot programs begin by resetting the machine, in case code such as the 16-colour code is already running.
30 ... Reset to root directory (matters more for ADFS)
40-60 ... Header
70-80 ... Initialise screen (80 is for 16 colours only)
90 ... Ensure that variables don't overrun
100 ... Turn cursor off
110-140 ... Initialise colour array (16 colours only)
150 ... Compile 16 colour code
160 ... Clear graphics window
170 ... Set the maximum number of iterations. With MI% at 600, the program takes ages to run - the more "sea" area there is, the longer it takes - sea pixels take MI% iterations each to plot whereas coloured ones take fewer iterations
180 ... Set pixel resolution for each axis. Change XN% to 2 for Mode 0 or 8 for Mode 2
190-200 ... Set axis steps. These variables enable approximate plots to be made in order to find a good bit of the Mandelbrot set to plot. There are 256 pixels on each axis (see line 230), so setting the steps to a power of 2 is what I have done when I wanted to find a good place to plot (the main reason for the steps is to save time - the plot to find "Sea-horse valley" took 20 minutes to run, the final 16 colour plot took over 37 hours!)
210-220 ... Set the coordinates for the plot. To get the full Mandelbrot set, make these lines read:
              210XL=-4:XR=4
              220YLO=-4:YUP=4
This plot should take little more than an hour with MI% set to 30 in line 170 (no need for high resolution for the full set)
230 ... Set the number of pixels on each axis. 256 each way leaves room for you to put the coordinates in the window on the right (similar to the Mandelbrot generator I saw on the A3000 at school a few years back)
240-380 ... Take the coordinates and interpolate between them to generate an array of points to plot
390-400 ... Set up a loop for each axis
410 ... Get the colour of each pixel (the time consuming bit)
420 ... Switch screens (16 colours only)
430 ... Set plotting colour
440 ... Plot the pixel
450-470 ... Plot the pixel on the other screen (16 colours only)
480-490 ... Close the axis loops
500-530 ... Save the picture (16 colour version has to set the memory accessed to be main or shadow RAM in order to save)
540 ... Reset cursor (16 colours only)
550 ... END
560-570 ... Data for the colour arrays (16 colours only). The first number gives the colour (0-3) which is plotted on the main screen, the second gives the colours for the Shadow screen, and so on for the others (third = main colour, fourth = Shadow colour etc...). The "sea" of the Mandelbrot is usually black (0,0), blue or white (colour selection depends on lines 1320-1410). Therefore you can select your preferred colour scheme within the colours defined for the mode by changing these lines. You will need 32 numbers for 16 colour Mode 1, or 72 for 36 colour Mode 2
580 ... Blank
590-730 ... This is the clever bit - the Mandelbrot algorithm. The idea of the Mandelbrot set is to iterate the equation Z = Z^2 + C, where Z is a complex number, given by X + iY. Points which go infinite before MI% iterations have been done are plotted in a colour from the array, whereas points which have not gone infinite are plotted in the "sea" colour (the first colour in the array is reserved for the sea, so that you can plot a two colour picture by *LOADing SHVPIC1 at &3000 and doing VDU19s to set colours 1,2 and 3 to the same colour (with 16 colour Mode switched off with *FX 13,4))

To square a complex number, the X component becomes X squared - Y squared (because i is the square root of -1), and the Y component becomes 2 * X * Y.

The complex constant C is added to Z. C is made up of the coordinates of the pixel. Apologies to the those who hate Maths!

The Mandelbrot set is a 'map' of "Julia sets" (plot these by changing line 640 to:

              640I%=0:X1=X:Y1=Y
and removing the "+ X" or "+ Y" from lines 670 and 680. The best Julia sets to plot are found at the edge of the "sea" area of the Mandelbrot set.

HLT is a flag which indicates that the iterated complex number Z has gone theoretically infinite - a value of X^2+Y^2 of more than 16 is judged to be infinite. An alternative here is to use:

              700HLT=(ABS(X)+ABS(Y)>4)
which gives a similar effect, except that plotting from -4 to +4 on both axes gives a diamond as the first-iteration shape, rather than an ovoid.

I% is the number of iterations performed. If Z has gone infinite, the sea colour (0) is chosen, otherwise a number from 1 to 15 (1 to 3 for non-Shadow-RAM machines).

NB. For the Sea-horse Valley pictures I added lines 610-620. These cut out the bottom left corner and part of the right hand side respectively. Since 600 iterations takes so long to plot, I thought that adding two tests to every point plotted was an insignificant delay compared to the benefit of removing 3/8 of 65536 (=24566) points at the full 600 iterations!

I would advise you to do something similar if you intend to plot at more than 100 iterations with any significant sea area

740 ... Blank
750-790 ... Calculate the pixel offset - interpolate between pixels to give the array of decimal values of points to feed into the algorithm
800 ... Blank
810-1500 ... The 16-colour source code. An explanation of this is given separately

Mark Bellis, EUG #29