Fast Mandelbrot Zoomer in Assembler (32bit windows only)
This project was started to see if I could write a fast Mandelbrot zoomer from scratch in assembler in one evening utilizing the FPU (Float Point Unit) for the math part. I almost succeeded, and the few bugs that I couldn’t find the first day, was found the following morning.
(This was also an exercise in writing Windows assembler, something I haven’t done since I owned a 386 based PC!)
Development
First version
In the first version of the program I took a straightforward approach to calculating the Mandelbrot set: Scanning all columns and rows and calculating whether or not the corresponding complex point was part of the Mandelbrot set or not. If not, I plot a pixel in a color corresponding to the time where the point escaped the set.
The program is written for Windows (DOS) exclusively, using the NASM assembler. The output is a Windows binary COM file. The image is drawn directly into the video buffer and the first version only supported MCGA 320×200, 256 colors and a fixed palette.
Second version
- Version 2.0.1 First release
- Version 2.0.2 Fixed “reset” bug when changing palette; Added 3 palettes
- Version 2.0.3 Program crashed when changing palette with large number of iterations
- Version 2.0.4 Supports different screen modes
With this approach I could prove that the FPU is lightningly fast, and well suited for these kinds of tasks. But I wanted to make it even faster, and also add a few more functionalities. So I added a few more palettes, added support for all the most common VESA graphics modes, and made it possible to change the number of max iterations while the program was running.
The new method I came up with for calculating the Mandelbrot set relies on a property of the Mandelbrot fractal that says that: For any closed curve that lies within the Mandelbrot, the points that it surrounds will also lie within the Mandelbrot set (insert reference here).
My first approach was to make a crawler, somthing which I have successfully implemented in C before. But this seemed a bit daunting for an assembler program, and would also have required a lot of memory allocation. Instead, inspired by Joachim, I implemented a simpler strategy, where the area to be rendered is divided in a number of sub-squares. The border of each square is first calculated, and if all points have the same color, the square is filled with that color! If not, the contents is rendered the traditional way. This made the program a lot faster.
Third version (future)
This version should support writing the output to a file, but this hasn’t been implemented yet. There is also a bug: when you zoom in very close, the graphics doesn’t render correctly.
User manual
There is no user manual built into the program (to reduce file size). Instead refer to this online guide:
| KEY(S): | FUNCTION: |
|---|---|
| Cursor keys | Scroll up, down, left, right |
| PageUp/Dn | Zoom in/out |
| Home/End | Increase/Decrease maximum number of iterations (changes in powers of 2). Default is 256 iterations. |
| Insert/Delete | Cycle through palettes. Default is palette 1 (palette 0 is a b/w palette) |
| 0,1,2,3,4 | Set screen mode (and reset zoom)
Default is 4. |
| h | Return to original position and zoom level (home) |
| Escape | Quit program |
Note: This program is a COM file (a windows binary file) and not an EXE file. You can run this program like a normal program, but an over zealous virus checker might complain when you download it or run it - just ignore them.
The program accesses the hardware layer directly and will probably not run in WINE etc.
