
AMandel 1.28 (Windows) (80K)
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!
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 provided "as-is". The user alone will be held responsible for any consequences of use or misuse of this software.
Copyright © 1999-2009 by Amichai Rothman. All rights reserved.
If you find this software useful please consider supporting it by contributing a donation.
Please write in to report bugs, problems, suggestions, ideas, questions, answers, source code queries and especially just to let me know you've found AMandel useful. Getting feedback will encourage me to continue development and add some advanced features I have in mind...
For updates and additional information, you can always visit the website at
//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;