Fun with Mandelbrot sets. I never thought I’d say that, but here I am doing just that on the ZX81. I ran across some fun discussions on them. They are often used as benchmarks, but I just wanted to create some interesting pictures. This is my version using Sinclair BASIC that creates a few interesting ones.
# Not that detailed.
The downside to the ZX81 is that it doesn’t have a great display. It is only 64 by 24, or 64x28 if you poke into the bottom two lines. Having only two colors, black or white (on/off), doesn’t make it any better. However, that limitation doesn’t mean that you can’t make interesting images.
My goal wasn’t to make the traditional image, but something zoomed in. There are a lot of interesting frames you can get with the set. But the problem is how slow the ZX81 is. The first couple of versions I tried were horrible. I needed to do something different.
# Speeding things up.
The code I was using from Rosetta Code. Since I had already heard the ZX81 BASIC version wasn’t that fast, I looked at the other versions first. I tried an Apple ][ version, but it didn’t make a great image and wasn’t much better. Plus, I wasn’t sure I was converting the colors to black and white correctly.
That made me look for another version. I decided to convert the Commander X16 BASIC version. It wasn’t much different from the Apple ][ code, but was a bit easier to read. After typing it in, for some reason things still didn’t look correct. I found myself tweaking the code in an attempt to get it to display something closer to the classic Mandelbrot fractal.
The first and obvious change I made was to run in
FAST mode. That helped speed things up a little bit. The next fix was to adjust the iterations. Obviously, higher values improve accuracy, but given the limited resolution I could get away with a much lower value. With these changes in place, I was down to about 15-20 seconds a line which was a big improvement.
# Making the pictures look better.
Now the next challenge was actually getting a decent picture. I didn’t realize why the program was painting the pixel twice. I had removed one since I didn’t think I needed it. The problem was the picture was only plotting half the image. Then it dawned on me, it was using symmetry to print the other half faster.
I put the second plot back and finally got a correct image. That looked pretty good, but didn’t fit on the screen. I adjusted the zoom factor until I got an image that fit nicely. Although the standard image now looked correct, it was off center. I adjusted a few parameters and finally I had an image I liked.
# Time to make something more.
Now, the challenge was making a more interesting image. For that, I had to start playing with the math. I decided to add in a shift and scale value that would progressively display an image that zoomed into the fractal. I left the symmetry to ensure the program remained fast. This took a bit of trial and error to get a series of images I thought would look good.
With that done, I wrapped up the values in a loop. The program just plots over the last image. I added a
PAUSE after each line I plot so you can gauge progress. I just left it running to test that it actually completed. It doesn’t make for a great screen saver, but you can remove line 530 if you want to watch it work. I don’t recommend it given how slow the code is.
# Future stuff.
Now, the real test would be to write an assembly version of the program. I haven’t tried to get floating point math working in Assembly before and it would be quite a learning experience. However, it would hopefully provide some speed to make the program more interesting to watch. In fact, I might have gotten a start on that already. I’ll share the results in a future blog article.