"The noblest pleasure is the joy of understanding"   (Leonardo da Vinci)
Website banner

Fast Mandelbrot Zoomer in Assembler

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!)

Skip to the user manual…

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)

  • 0: QVGA 320×200 pixels, 256 colors
  • 1: VGA 640×480 pixels, 256 colors
  • 2: SVGA 800×600 pixels, 256 colors
  • 3: XGA 1024×768 pixels, 256 colors
  • 4: SXGA 1280×1024 pixels, 256 colors

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.

[[[ Copyright (C) Thor Asmund 1998-2008 ]]]