presents:
AMandel

AMandel

Download

It's free! Latest release:

AMandel 1.28 (80K - Windows)

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!

How does it look?

Snapshot

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.

License

Copyright (c) 1999-2024 by Amichai Rothman. All Rights Reserved.

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 find this software useful please help support it by contributing a donation!

If you like it, why not give something back?

13aWWmQqkiYnpkWT7QmE9khnpuuuG48U7o

Contact

You can contact the author via e-mail at:

support@freeutils.net

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:

www.freeutils.net

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
        fadd st(0), st(2)  //+Cr
        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
        fadd st(0), st(1) //+Ci
        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
        fadd st(0), st(1) //Zr*Zr+Zi*Zi

        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;