Making a better Mandelbrot Set on the ZX81 using High Resolution Graphics
Prompted to try out high resolution graphics, I used the ARX technique to give an older program a facelift.
One thing I hadn’t done before on the ZX81 was hires graphics. There are numerous reasons, but in general it was because I hadn’t tried. That changed after being encouraged in my ZX81 group to use with with Mandelbrot Set program. So I did.
# Coding ahead.
Okay, let’s talk with about that encouragement. Wayne was playing around with HRG-MS or High Resolution Graphics (HRG) for the ZX81. As the ZX81 doesn’t have native HIRES graphics, you need a graphics capable RAM pack for this to work. Now, in doing so, he also made sure to tag me in a comment:
His idea was for me to convert my Mandelbrot Set program into hires. After noting that I hadn’t programed in HRG before, Wyane prodded me further. Sometimes you need a push. After some pondering, I decided “why not?” and promptly got to coding.
# Starting down a path, but not the one intended.
Now part of the reason I hadn’t used HRG before was because you need a driver for it. As noted, the ZX81 doesn’t do HRG natively. The display routine built into the machine is designed for static characters in a 32x24 grid. Given there is no dedicated display chip like many other computers, this results in the CPU spending a lot of time printing the display.
Now, there are a few tricks to get this to work. When you run in FAST
mode, that display routine is turned off. When that happens, you could use your own display routine and quite a few folks have done just that. Some use what is called pseudo-hires where the display routine uses existing blocks in memory to display more granular patterns. This works, but often leaves artifacts.
HRG-MS, as noted above, uses a different approach by using a hardware approach. Although I like this approach, the drivers are often designed to be loaded first. You do this by adjusting RAMTOP, loading in the code for HRG, then loading your BASIC or other program. This works great, but I wanted a self-contained program.
# Heading to the left.
Doing some searching, I ran across another this article for using ARX to do high resolution graphics on the ZX81. Originally designed by Andy Rea in 2006, hires graphics are displayed using user defined graphics (UDG) memory. Like other HRG routines, it does require some RAM mapping.
Now the reason for ARX was because Paul Farrow provided a modified display driver that I could easily include into my program. Before I could do anything with my Mandelbrot program, I needed to understand how to use it. To do that, I took a look at Paul’s demo code which was similar to how I write code for the ZX81. To test it out, I shoe horned the code into one of my templates. This gave me an opportunity to understand how to use ARX while also making sure it compiled correctly.
The last step was to ensure the code worked in my emulators. EightOne was pretty straight forward, which was good as I use that emulator for all my pictures. ZXSP worked after testing a few different RAM packs. The last, and arguable the most important, was to get it work in JSZeddy.
JSZeddy does support ARX. I was able to get the program to run great in the emulator on the site, but it required the user to change graphics modes. I didn’t want the user to have to do anything, so I started to hack the javascript to see if I could force it. Then, after reading the manual, I realized ARX would load by default if the file had ARX in the name. After a quick check, I had the demo program running perfectly. I was now ready to do some coding.
# Making a hires Mandelbrot Set.
Fortunately, converting MBS would be straightforward. The program was already modular given the three different versions I had written. I started by adding in the initialization code and including the plot routine from the demo program. After a recompile, I had the program running.
There was, however, a minor issue. The Mandelbrot Set was tiny! This required me to adjust the scaling factors in my program. Although the math is faster in assembly, it is still pretty slow. Fortunately, I could run the emulator faster making testing a little easier. With the scale done, I had my first image an it looked great.
Mandelbrot Set in ARX HIRES, 2024 by Steven Reid
# The Plot Routine
Although the plot routine worked great, I did have one challenge. My code also un-plotted pixels. This required me to read up a bit on how the ARX routine was painted in memory and then how the plot routine worked.
I won’t go through all the details as you can review them in the code. But the gist is that the routine has to compute the pixel location based on a column and row format. The plot routine computes the location which is held in HL. The pixel location is stored in register B and the bit is then shifted into location in register A.
At this point, we know what pixel to set or unset. The exiting plot routine takes the pixel in register A and combines it with the exiting pixels at memory local HL. This is done withe following code:
plot_pixel:
or (hl) ; Combine the pixel with the current display file location byte.
ld (hl),a ; Write the new pixel pattern back into the display file.
ret
To remove a pixel, I needed to do a little bitwise math. To erase a pixel, I had to figure out how to invert only the specific bit corresponding to the pixel, leaving the rest untouched. This required a combination of XOR to flip the bit and AND to mask it out. The final code looks like this:
unplot_pixel:
ld b,255
xor b ; Convert to a mask to remove a pixel
and (hl) ; And the mask with the current display file location byte.
ld (hl),a ; Write the new pixel pattern back into the display file.
ret
# A fun exercise.
Thanks to Wayne, I now had a much more interesting version of my Mandelbrot Set program. It was a fun experiment that wasn’t as hard I thought it would be. The ZX81 is still slow for this kind of stuff, but it works.
Mandelbrot Set in ARX HIRES, 2024 by Steven Reid
Now that I have working routine, it would be fun to find new ways to use it. I’ve had a few ideas of creating a graphic adventure game. I’d need to add in line and circle routines, but shouldn’t be too hard. I had thought of doing this with regular graphics, but HRG would allow more details.
Mandelbrot Set in ARX HIRES, 2024 by Steven Reid
More interesting would be to add in pattern fill. This would allow more interesting visuals given the higher resolution. Adding to the challenge, I haven’t done a fill routine yet. Together I could envision a decent little graphics engine. The challenge is writing a program around it. The one thing I haven’t figure out yet is adding in text. That might require another routine.
Mandelbrot Set in ARX HIRES, 2024 by Steven Reid
Sticking with the current, I’m happy to have a better looking Mandelbrot Set on the ZX81 and a better understanding of how high resolution works on the ZX81. Thanks, Wayne.
Mandelbrot Set in ARX HIRES, 2024 by Steven Reid