program mandelbrot1;
{First demo of drawing a Mandelbrot Set. This program merely
demonstrates the basics of calculating and plotting.}
uses crt; {A unit that allows us to read single keypresses.}
{Note to C programmers: the variable type "real" is equivalent
to the C type "float".}
var cx,cy: real; {Where do we want to center the brot?}
scale: real; {This is the "zoom" factor.}
limit: word; {Divergence check value.}
lp: word; {Convergence check value.}
a1,b1,a2,b2: real; {For calculating the iterations.}
x,y: integer; {The pixel we are drawing.}
ax,ay: real; {The actual position of (x,y) in relation to
the Mandelbrot set.}
key: char; {Dummy value for keypresses.}
procedure init256;
{Initialises a VGA mode 320x200 pixels, 256 colours. A little chunky
but the extra colours are worth it, and SVGA is beyond the scope of
this program.}
begin
asm
mov ah,0
mov al,$13
int $10
end;
{This is a little direct assembly language. Feel free to use this
routine, and the others that follow, in your own code.}
end;
procedure end256;
{Turns off the video mode and returns to standard 16-colour text mode.}
begin
asm
mov ah,0
mov al,$03
int $10
end;
end;
procedure pixel(a,b: word; c: byte);
{This procedure plots a pixel at screen coordinate (a,b) in colour c.
Again, there is no need for you to understand the intrinsic workings
of this routine - you are welcome to use it in your programs but do
be aware that silly values for a and b could cause unexpected results.}
var v: word;
begin
v:=a+b*320;
mem[$A000:v]:=c;
end;
begin
{Set up video mode.}
init256;
{Set up initial values for drawing. Try compiling the program
with different values here if you like!}
cx:=0; cy:=0; scale:=0.02;
limit:=4;
{Loop through all pixels on screen. For reasons that will become
clear, I am counting not from (0,0) but from (-160,-100).}
for x:=-160 to 159 do
for y:=-100 to 100 do begin
{What is the *mathematical* value of this point?}
ax:=cx+x*scale; ay:=cy+y*scale;
{And now for the magic formula!}
a1:=ax; b1:=ay; lp:=0;
repeat
{Do one iteration.}
lp:=lp+1;
a2:=a1*a1-b1*b1+ax;
b2:=2*a1*b1+ay;
{This is indeed the square of a+bi, done component-wise.}
a1:=a2; b1:=b2;
until (lp>255) or ((a1*a1)+(b1*b1)>limit);
{The first condition is satisfied if we have convergence.
The second is satisfied if we have divergence.}
{Define colour and draw pixel.}
if lp>255 then lp:=0;
{If the point converges, it is part of the brot and we
draw it with colour 0, or black.}
pixel(x+160,y+100,lp);
end;
{Wait for keypress and return to text mode.}
key:=readkey;
end256;
{Note: newer versions of Turbo Pascal do not need the
dummy value "key", but in case you are using a version
that can't I've built in a little redundancy!}
end.