presents:

# AMandel

It's free! Latest release:

## What is AMandel?

AMandel is an application that lets you view the fractal known as the "Mandelbrot Set", named after Benoit Mandelbrot. You can view any area of the set, with resolution limited only by the computer's processing capabilities.

The main calculations are implemented in assembly language using the Floating Point Unit (FPU) stack and further optimizations for highest speed and performance.

Features include Zoom capabilities, manually entering coordinates, saving image as bitmap, copying image to clipboard, printing image, traversing a history list of visited locations (zooms & unzooms), as well as loading and saving of coordinates for further explorations.

Enjoy!

## Installation Notes

To install AMandel, Double-Click the setup file. This will start a Setup Wizard that will guide you through the simple installation process.

To uninstall AMandel, select Uninstall from the AMandel Start Menu group, if you selected this option during installation, or run Uninstall from the installation folder.

This Software is Freeware.

You may make copies, install and run it free of charge.

You may redistribute it to others, complete and unmodified from its original binary form, as long as you do so free of charge as well.

For non-commercial use only.

If you like it, why not give something back?

## Contact

You can contact the author via e-mail at:

Please write in with any bugs, suggestions, fixes, contributions, or just to drop a good word and let me know you've found AMandel useful and you'd like it to keep being maintained.

For updates and additional information, you can always visit the website at:

## Code

The main calculation (for each pixel) using the FPU follows. If you find any further optimizations, please let me know!

``````
//the original routine in Pascal
{     Repeat
Begin
RunAwayCount:=RunAwayCount+1;
t:=Zr;
Zr:=(t*t)-(Zi*Zi)+Cr;
Zi:=(2*t*Zi)+Ci;
end;
until (RunAwayCount>RP.iIterate)or(((Zr*Zr)+(Zi*Zi))>MaxDistance);
}

//and the FPU implementation
asm
push eax
push ecx
push edx
mov edx, dword ptr [iIterate]
ffree st(0) //clear FPU stack so we have room for register vars
ffree st(1)
ffree st(2)
ffree st(3)
ffree st(4)
ffree st(5)
ffree st(6)
ffree st(7)
mov ecx,0 //RunAwayCount:=0
fild dword ptr [MaxDistance]
fldz //Zr=0
fldz //Zi=0
fld tbyte ptr [Cr] //leave Cr in register
fld tbyte ptr [Ci] //leave Ci in register
fldz    //initial Zi*Zi
fldz    //initial Zr*Zr

@@calcloop:
fxch st(1) //Zr before Zi. pairs nicely with cpu's inc ecx
inc ecx  //RunAwayCount:=RunAwayCount+1

fsubp st(1), st(0)  //Zr*Zr-Zi*Zi
fxch st(4) //Zr:=Zr*Zr-Zi*Zi+Cr, bring old Zr for Zi's calculation

fadd st(0), st(0)   //2*Zr (old Zr)
fmul st(0), st(3) //2*Zr*Zi
fst st(3)  //Zi:=2*t*Zi+Ci   and leave it in st(0) for later

cmp ecx, edx  //RunAwayCount>IterateTest?
jg @@calcend

fmul st(0), st(0) //Zi*Zi
fld st(4)  //Zr
fmul st(0), st(0) //Zr*Zr
fld st(1)         //make copy of Zi for calculation so we can leave
//Zr*Zr and Zi*Zi in regs for next loop

fcomp st(7)  //(Zr*Zr)+(Zi*Zi)>MaxDistance?
fstsw ax                        //FPU results to ax
sahf                            //ax to flags
jbe @@calcloop

@@calcend:
mov dword ptr[RunAwayCount],ecx
ffree st(0) //release register vars
ffree st(1)
ffree st(2)
ffree st(3)
ffree st(4)
ffree st(5)
ffree st(6)
ffree st(7)
pop edx
pop ecx
pop eax
end;
``````