Border tracing Mandelbrot generator for the Beeb

discussion of beeb/electron applications, languages, utils and educational s/w
User avatar
Rich Talbot-Watkins
Posts: 1078
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Border tracing Mandelbrot generator for the Beeb

Postby Rich Talbot-Watkins » Tue Oct 25, 2016 9:52 pm

A long, long time ago, Matt [Godbolt] and I submitted a program to Acorn User's "*Info" column which generated Filled Julia Sets on the Beeb - we'd just learnt how to do multiplication on the 6502, and it seemed like a good application for it. But it wasn't a particularly fast routine, and although we were proud of it at the time, there was undoubtedly a ton of room for improvement. It did earn us fifty quid though :lol:

Image

Fast forward, erm, 25 years... :shock: ...and I was thinking about something I'd seen in the past where Mandelbrots were rendered using a border tracing algorithm. Basically the idea is that, if you can identify where the colour boundaries are, you only need to iterate the Mandelbrot function there, and you can then do a simple flood fill on any areas which are left. I was wondering if this could be done on the Beeb, so, a few evenings later and voilà!, a new Mandelbrot program was born!

Image Image

The disk image and source code are attached. Once it's finished drawing, you can move the zoom selection box around with ZX:/ and Return to select. For simplicity, there's no way to resize the box - it always zooms to 1/4 of the previous zoom (how convenient). Escape returns you to the fully zoomed out parameters. In very detailed bits of fractal, sometimes it runs out of stack and makes a total mess of everything, need to try and correct that!

If anyone can think of more ways to speed it up, I'd love to know! I actually expected it to run a bit faster than it does with the super optimized multiplication routine, but I think I'm finally at peace with the idea that the 6502 was never really meant to calculate Mandelbrots. Still, it's fun to see it working on the Beeb, even if it takes a minute or so to get there...

Mandelbrot.zip
(9.91 KiB) Downloaded 51 times

Edit: new version below

User avatar
hoglet
Posts: 6352
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol

Re: Border tracing Mandelbrot generator for the Beeb

Postby hoglet » Tue Oct 25, 2016 9:59 pm

Any chance this could be made to run on a 6502 Co Pro (it does't seem to currently).

I'd love to run it on a 250MHz 6502 :shock:

User avatar
Rich Talbot-Watkins
Posts: 1078
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Border tracing Mandelbrot generator for the Beeb

Postby Rich Talbot-Watkins » Tue Oct 25, 2016 10:02 pm

Just uploaded a new version, but it'll never run on a second processor as-is. It's doing everything illegal - screen access and keyboard access - and turns off IRQs and shuts the OS out, mostly so I can use as much of the OS's memory as possible in order to give it more space for its stack.

Writing a second processor version would be the next step I guess!

User avatar
Rich Talbot-Watkins
Posts: 1078
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Border tracing Mandelbrot generator for the Beeb

Postby Rich Talbot-Watkins » Wed Oct 26, 2016 6:55 am

Added a new version here.

This imposes a maximum zoom level (as precision issues mean that it looks rubbish after the 5th zoom in), and checks for stack becoming full so it doesn't walk all over the multiplication tables and make everything look horrible. Also, lurkio pointed out that it needs a higher load address so that the open !Boot file doesn't complain when the executable is loaded - now fixed too, thanks!

The next way it could be improved would be to increase the precision, maybe using 64 bit values, and/or a floating point type model rather than the fixed point representation it currently uses. Also could do with increasing the maximum number of iterations it does as the zoom level gets higher.
Attachments
Mandelbrot.zip
(10.34 KiB) Downloaded 48 times

User avatar
PitfallJones
Posts: 428
Joined: Fri Feb 22, 2008 3:44 pm
Contact:

Re: Border tracing Mandelbrot generator for the Beeb

Postby PitfallJones » Thu Oct 27, 2016 1:00 am

Fascinating!

I've never seen this method before - quite hypnotic to watch (especially in an emulator running fast)

The color hatching is very nice as well

PJ

User avatar
Rich Talbot-Watkins
Posts: 1078
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Border tracing Mandelbrot generator for the Beeb

Postby Rich Talbot-Watkins » Thu Oct 27, 2016 8:04 am

Thanks!

I'd forgotten quite how bad the 6502 is at doing this sort of thing, so I decided to dig out the Acorn User disc from August 1990 to look at their Mandelbrot program, which promised "Mandelbrots at a speed you have never seen before"!

Here's the output compared to my program:
Image Image

The Acorn User program took 496 seconds to generate that image at a resolution of 80x128, with a maximum of 40 iterations before deeming a pixel to be in the Mandelbrot set.

Mandelbeeb takes 98 seconds at double the resolution (160x128), with a maximum of 32 iterations.

The big win comes from the border tracing algorithm. The pixels which lie in the Mandelbrot set (the black ones) are the slowest to calculate as they have to undergo the maximum number of iterations, and we save a huge amount of processing by only needing to evaluate the pixels which form the outline. The table-based multiplication also makes a difference - my guess is that a more naive multiplication routine would maybe double the time taken.

I've been thinking about how this would be adapted to run on the second processor. It'd have to use legal methods, i.e. using the VDU PLOT codes to output pixels, which is fine. A small issue is that the code currently uses the top bit of each pixel as a flag - each Mandelbrot pixel is made up of two screen pixels; the top bit of the top pixel is used to indicate that the pixel's colour hasn't yet been calculated, and the top bit of the bottom pixel is used to indicate that this pixel has already been put in the stack to be processed (so that it's not added again by a different neighbour). It'd be a big bottleneck to convert this to use the OSWORD to read a screen pixel, so I'd need to maintain a couple of buffers instead. Perfectly doable with all the second processor memory, but not such a trivial change. When I have time I'll give it a go.
Attachments
Acorn User (1990-08) - Mandelbrot.zip
(9.29 KiB) Downloaded 29 times

User avatar
jgharston
Posts: 2658
Joined: Thu Sep 24, 2009 11:22 am
Location: Whitby/Sheffield

Re: Border tracing Mandelbrot generator for the Beeb

Postby jgharston » Thu Oct 27, 2016 11:07 am

If you're manipulating pixels directly, the simplest thing do do would be to have a buffered mirror of the screen memory, manipulate that, then blat across the whole screen when you've finished. You would probably be able to use the same code with just a final 'if on CoPro then copy screen buffer'.

Eg:
screen=&3000
LDA #130:JSR OSBYTE:STY tubeflag
...
manipulate screen contents
LDA tubeflag:BMI done
copy screen buffer from &3000-&7FFF locally to &3000-&7FFF in I/O processor
.done

The default copy-across-tube calls (OSWORD 5 and 6) are very slow for large amounts of data, so it would probably be worth installing OSWORD &FF and calling it to chuck the entire 20K across in one go. (link)

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.25
(C) Copyright J.G.Harston 1989,2005-2015
>_

User avatar
Rich Talbot-Watkins
Posts: 1078
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Border tracing Mandelbrot generator for the Beeb

Postby Rich Talbot-Watkins » Thu Oct 27, 2016 11:28 am

Then you wouldn't see it building up the image as it drew the outlines, which is the fun thing about the program and probably the only thing that makes the wait bearable! I don't know what the overhead is for sending two GCOL and PLOT commands (VDU 16,0,c,25,a,x;y;) across the TUBE to the I/O processor - I would assume that a single GCOL/PLOT call is probably pretty quick as it fits in the 10 byte FIFO, but that queuing two of them would cause a bottleneck while the TUBE FIFO was flushed. I'd certainly need to keep a mirror of the screen anyway, because it also acts as a cache of already-calculated values (along with the two flag bits).

Seems to me like the only way to handle this would be to adopt Elite's method and intercept WRCHV on the host, and have it interpret VDU a,b,c as GCOL 0,a; PLOT 69,b*8,c*4. Sounds like a lot more work though...

User avatar
hoglet
Posts: 6352
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol

Re: Border tracing Mandelbrot generator for the Beeb

Postby hoglet » Thu Oct 27, 2016 11:47 am

Rich Talbot-Watkins wrote:Then you wouldn't see it building up the image as it drew the outlines, which is the fun thing about the program and probably the only thing that makes the wait bearable! I don't know what the overhead is for sending two GCOL and PLOT commands (VDU 16,0,c,25,a,x;y;) across the TUBE to the I/O processor - I would assume that a single GCOL/PLOT call is probably pretty quick as it fits in the 10 byte FIFO, but that queuing two of them would cause a bottleneck while the TUBE FIFO was flushed. I'd certainly need to keep a mirror of the screen anyway, because it also acts as a cache of already-calculated values (along with the two flag bits).

Seems to me like the only way to handle this would be to adopt Elite's method and intercept WRCHV on the host, and have it interpret VDU a,b,c as GCOL 0,a; PLOT 69,b*8,c*4. Sounds like a lot more work though...

The FIFO is 24 bytes deep, so I think it would work very nicely.

User avatar
Rich Talbot-Watkins
Posts: 1078
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Border tracing Mandelbrot generator for the Beeb

Postby Rich Talbot-Watkins » Thu Oct 27, 2016 11:50 am

Ah right! I was looking at http://www.sprow.co.uk/bbc/hardware/armcopro/004.pdf which said it was a 10 byte FIFO, but maybe the hardware buffer is 10 bytes, while the TUBE interrupt system implements a 24 byte FIFO which fills the TUBE hardware without blocking? Or maybe that documentation is just wrong?

User avatar
Rich Talbot-Watkins
Posts: 1078
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Border tracing Mandelbrot generator for the Beeb

Postby Rich Talbot-Watkins » Thu Oct 27, 2016 11:52 am

That said, I quite like the elegance of a custom host WRCHV which can plot double pixels in colour 0-32 (performing the appropriate stippling), just with a simple VDU sequence (it could also do direct screen access to permit larger-than-MODE 2 screens). But it's a bit more effort to do!

User avatar
hoglet
Posts: 6352
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol

Re: Border tracing Mandelbrot generator for the Beeb

Postby hoglet » Thu Oct 27, 2016 12:04 pm

Rich Talbot-Watkins wrote:Ah right! I was looking at http://www.sprow.co.uk/bbc/hardware/armcopro/004.pdf which said it was a 10 byte FIFO, but maybe the hardware buffer is 10 bytes, while the TUBE interrupt system implements a 24 byte FIFO which fills the TUBE hardware without blocking? Or maybe that documentation is just wrong?


I think it meant the maximum VDU command length was 10 bytes.

Later on is says:
- Register 1 (24 byte FIFO read only)

The Acorn TUBE ULA is 24 bytes, the Pi Tube Direct is 24 bytes, the Matchbox Co Pro is 32 bytes, and I think some of John Kortink's designs (e.g. ReTuLa) are only one byte. So your mileage may vary.

Dave

User avatar
Rich Talbot-Watkins
Posts: 1078
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Border tracing Mandelbrot generator for the Beeb

Postby Rich Talbot-Watkins » Thu Oct 27, 2016 12:30 pm

Ah cool!

I'm not so familiar with the second processor... is there some way for the parasite to upload code to the host and execute it there? Just to set up vectors and this kind of thing?

User avatar
hoglet
Posts: 6352
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol

Re: Border tracing Mandelbrot generator for the Beeb

Postby hoglet » Thu Oct 27, 2016 12:36 pm

Rich Talbot-Watkins wrote:Ah cool!

I'm not so familiar with the second processor... is there some way for the parasite to upload code to the host and execute it there? Just to set up vectors and this kind of thing?

OSWORD A=5 and A=6 allow the parasite to read and write host memory (one byte at at time).

That lets you do pretty much anything you want.

You could, for example, upload some code and then redirect either OSWRCH or the USER Vector.

User avatar
Rich Talbot-Watkins
Posts: 1078
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Border tracing Mandelbrot generator for the Beeb

Postby Rich Talbot-Watkins » Thu Oct 27, 2016 12:43 pm

Yep, OSWORD 5 and 6 I knew about. What I'm wondering is how to get the host to execute arbitrary code. Can this only be done by intercepting vectors and going through the supported protocols (OSWRCH, OSBYTE etc), or is there some other way specifically designed to allow this? Obviously I can do anything by just literally writing WRCHV on the host with OSWORD 6 and reserving various VDU codes to perform different host operations, but I was wondering if there were a less hacky way.

User avatar
hoglet
Posts: 6352
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol

Re: Border tracing Mandelbrot generator for the Beeb

Postby hoglet » Thu Oct 27, 2016 12:53 pm

Rich Talbot-Watkins wrote:Yep, OSWORD 5 and 6 I knew about. What I'm wondering is how to get the host to execute arbitrary code. Can this only be done by intercepting vectors and going through the supported protocols (OSWRCH, OSBYTE etc), or is there some other way specifically designed to allow this? Obviously I can do anything by just literally writing WRCHV on the host with OSWORD 6 and reserving various VDU codes to perform different host operations, but I was wondering if there were a less hacky way.

I can't think of a cleaner way to execute arbitrary code on the host.

What the Z80 Co Pro does is install it's own User Vector handler (with OSWORD 6), then that gets called by *LINE, *CODE, OSWORD >=&E0. Problem is, that slow, and is blocking (on the parasite side).

I think you do need to intercept the OSWRCH handler and install your own. That's the only way you'll then benefit from the 24-byte FIFO.

User avatar
Rich Talbot-Watkins
Posts: 1078
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Border tracing Mandelbrot generator for the Beeb

Postby Rich Talbot-Watkins » Thu Oct 27, 2016 1:35 pm

Thanks. I'll give it a go some time! Would definitely expect to see a 2x speed increase on a 4MHz 6502. To be honest though, there's unlikely to be a lot of speedup from running the calculations and plotting in parallel - the plotting code is a tiny fraction of the processing compared to iterating the Mandelbrot function. Unlike Elite, which benefits from the both the faster 6502 and the parallelisation of the maths and the line drawing.

User avatar
hoglet
Posts: 6352
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol

Re: Border tracing Mandelbrot generator for the Beeb

Postby hoglet » Thu Oct 27, 2016 1:55 pm

Rich Talbot-Watkins wrote:Thanks. I'll give it a go some time! Would definitely expect to see a 2x speed increase on a 4MHz 6502. To be honest though, there's unlikely to be a lot of speedup from running the calculations and plotting in parallel - the plotting code is a tiny fraction of the processing compared to iterating the Mandelbrot function. Unlike Elite, which benefits from the both the faster 6502 and the parallelisation of the maths and the line drawing.

I'd like to run it on the 250MHz 6502 Co Pro!

User avatar
Rich Talbot-Watkins
Posts: 1078
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Border tracing Mandelbrot generator for the Beeb

Postby Rich Talbot-Watkins » Thu Oct 27, 2016 1:58 pm

Well, that'd probably run fairly quickly! (I hadn't even realised you could clock a 6502 at 250MHz!)

User avatar
hoglet
Posts: 6352
Joined: Sat Oct 13, 2012 6:21 pm
Location: Bristol

Re: Border tracing Mandelbrot generator for the Beeb

Postby hoglet » Thu Oct 27, 2016 2:04 pm

Rich Talbot-Watkins wrote:Well, that'd probably run fairly quickly! (I hadn't even realised you could clock a 6502 at 250MHz!)

You can't, not a real one any way. It's an emulation on a Pi Zero.

Dave

User avatar
jgharston
Posts: 2658
Joined: Thu Sep 24, 2009 11:22 am
Location: Whitby/Sheffield

Re: Border tracing Mandelbrot generator for the Beeb

Postby jgharston » Thu Oct 27, 2016 3:05 pm

Rich Talbot-Watkins wrote:Yep, OSWORD 5 and 6 I knew about. What I'm wondering is how to get the host to execute arbitrary code.

This was discussed some months ago. You alter USERV to point to the code, then make a call that calls USERV. The Wiki has sample code.

Code: Select all

$ bbcbasic
PDP11 BBC BASIC IV Version 0.25
(C) Copyright J.G.Harston 1989,2005-2015
>_

User avatar
BigEd
Posts: 1389
Joined: Sun Jan 24, 2010 10:24 am
Location: West
Contact:

Re: Border tracing Mandelbrot generator for the Beeb

Postby BigEd » Thu Oct 27, 2016 3:32 pm

To intercept and extend the VDU protocol properly, you'd need the host-side code to model the lengths of all the VDU control operations. Which is not terribly hard, I suppose. But to do a quick and dirty job for a specific purpose, it's enough to model only the lengths which you'll use. It might even be possible to ignore the length problem, if you can arrange that some values will never appear as operands to control codes: FF and FE for example might not be used by your application, and could therefore be used for extended operations, such as a one-byte update.

User avatar
Rich Talbot-Watkins
Posts: 1078
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Border tracing Mandelbrot generator for the Beeb

Postby Rich Talbot-Watkins » Thu Oct 27, 2016 4:31 pm

New version!

Now it looks like all the outlines are grown in parallel from the outside inwards - not sure if this is more or less visually interesting, but it has lower space requirements, so it's probably here to stay.

Changed to a big overscan MODE 2 (184x272)!
Attachments
Mandelbrot.zip
(10.53 KiB) Downloaded 62 times

User avatar
Rich Talbot-Watkins
Posts: 1078
Joined: Thu Jan 13, 2005 5:20 pm
Location: Palma, Mallorca

Re: Border tracing Mandelbrot generator for the Beeb

Postby Rich Talbot-Watkins » Thu Oct 27, 2016 4:34 pm

@jgh: Thanks for the tip - nice to know what my options are.
@Ed: This would be a complete replacement for the VDU drivers, it wouldn't be supporting any of the real control codes, so I'd be free to implement it as I wished. I'd probably just say VDU c, x, y plots two pixels in colour 0-32 (with dithering), at (x,y) in screen pixels from the top left. Then would make exceptions for special values of c, to do things like clearing the screen, setting palettes, plotting the selection box, etc.

User avatar
SimonSideburns
Posts: 251
Joined: Mon Aug 26, 2013 8:09 pm
Location: Purbrook, Hampshire
Contact:

Re: Border tracing Mandelbrot generator for the Beeb

Postby SimonSideburns » Fri Oct 28, 2016 11:30 pm

Of course the next possible speedup is to realise that if you have the 0 imaginary axis somewhere within your top y and bottom y range then the negative value pixels are the same as the positive values (e.g. the image is mirrored at the 0 coordinate on the imaginary axis).
I'm writing a game where you can change your character from a Wizard to a monkey to a cat.

Well, Imogen that!

SteveF
Posts: 429
Joined: Fri Aug 28, 2015 8:34 pm

Re: Border tracing Mandelbrot generator for the Beeb

Postby SteveF » Fri Oct 28, 2016 11:44 pm

jgharston wrote:
Rich Talbot-Watkins wrote:Yep, OSWORD 5 and 6 I knew about. What I'm wondering is how to get the host to execute arbitrary code.

This was discussed some months ago. You alter USERV to point to the code, then make a call that calls USERV. The Wiki has sample code.

There's also Tom Seddon's page at http://ffe3.com/tom/tube.html which discusses some techniques. And if you're doing this in BeebAsm, you might want to pick up the patch at http://www.retrosoftware.co.uk/forum/vi ... =17&t=1018 which allows saving files to the generated disc image with the high bits set on the load/execution addresses.

litwr
Posts: 184
Joined: Sun Jun 12, 2016 8:44 am

Re: Border tracing Mandelbrot generator for the Beeb

Postby litwr » Sat Oct 29, 2016 3:15 pm

It is interesting coincidence that the similar threads present at Amstrad CPC and Commodore +4 forums. However they are about programs in Basic. I have just converted one from Commodore Basic to BBC Basic.
The original program.

Code: Select all

   10 x=0:y=0:x2=0:y2=0:xy=0:r=0:j=0
   11 dimd(2,319),r(319),j(199):a=0:b=1:c=2
   12 r0=-1.9:r1=+0.5:dr=(r1-r0)/320:fors=0to319:r(s)=r0+dr*s:next
   13 j0=-0.10:j1=+0.95:dj=(j1-j0)/200:fort=0to199:j(199-t)=j0+dj*t:next
   14 n=30
   15 color0,1:color1,4:graphic 1:ti$="000000":scnclr
   16 fort=0to199:j=j(t):fors=0to319:r=r(s):x=r:y=j
   17 fori=1ton:x2=x*x:y2=y*y:ifx2+y2<4thenxy=x*y:x=x2-y2+r:y=2*xy+j:next
   18 d(c,s)=i:ifi<=nthen:draw 1,s,t
   19 ifs<2ort<2then28
   20 locate s-1,t-1:if rdot(2)=0then28
   21 m=d(b,s-1)
   22 ifd(b,s-2)<mandd(b,s)<mthen27
   23 ifd(a,s-2)<mandd(c,s)<mthen27
   24 ifd(c,s-2)<mandd(a,s)<mthen27
   25 ifd(a,s-1)<mandd(c,s-1)<mthen27
   26 goto28
   27 draw 0
   28 nexts:z=a:a=b:b=c:c=z:next:printti:clk$=ti$
   29 getkeya$:graphic0:printclk$

The converted program

Code: Select all

   10 x=0:y=0:x2=0:y2=0:xy=0:r=0:j=0
   11 DIM d(2,319),r(319),j(199):a=0:b=1:c=2
   12 r0=-1.9:r1=.5:dr=(r1-r0)/320:FOR s%=0 TO 319:r(s%)=r0+dr*s%:NEXT
   13 j0=-0.10:j1=.95:dj=(j1-j0)/200:FOR t%=0 TO 199:j(199-t%)=j0+dj*t%:NEXT
   14 n=30
   15 MODE 4:TIME=0
   16 FOR t%=0 TO 199:j=j(t%):FOR s%=0 TO 319:r=r(s%):x=r:y=j
   17 FOR i=1 TO n:x2=x*x:y2=y*y:IF x2+y2<4 THEN xy=x*y:x=x2-y2+r:y=2*xy+j:NEXT
   18 d(c,s%)=i:IF i<=n THEN:PLOT 69,4*s%,800-4*t%
   19 IF s%<2 OR t%<2 THEN 28
   20 IF POINT(4*s%-4,804-4*t%)=0 THEN 28
   21 m=d(b,s%-1)
   22 IF d(b,s%-2)<m AND d(b,s%)<m THEN 27
   23 IF d(a,s%-2)<m AND d(c,s%)<m THEN 27
   24 IF d(c,s%-2)<m AND d(a,s%)<m THEN 27
   25 IF d(a,s%-1)<m AND d(c,s%-1)<m THEN 27
   26 GOTO 28
   27 PLOT 70,4*s%-4,804-4*t%
   28 NEXT s%:z=a:a=b:b=c:c=z:NEXT:clk=TIME/100:hours=INT(clk/3600):mins=INT(clk/60-hours*60)
   29 REM a$=GET$:IF a$="" THEN 29
   30 PRINT hours;":";mins;"-";INT(clk-hours*3600-mins*60)

I was curious to compare the speed.
Commodore 128 - 12h 54m 17s
Commodore 128 with SuperCPU (65816 at 20MHz) - 15m 2s
Commodore +4 - 10h 17m
Amstrad CPC6128 - 5h 27m 13s
BBC Model B (B-em) - 4h 35m 58s
BBC Master 128 (B-em) - 3h 23m 48s
BBC Master Turbo (B-em) - 1h 34m 32s
So it should be less than a minute for the fast 2nd processor.
BTW I would like to have a full throttle key for B-em...
mandel2.GIF

The link for more results is http://cbmandelbrot.blogspot.sk/. The link to Amstrad CPC and Dragon-32/64 pictures is http://www.cpcwiki.eu/forum/demos/mandelbrot-with-amstrad/. It also contains a link to one line Basic program which draws Mandelbrot.
Excuse me if my material is a bit off topic.

SarahWalker
Posts: 1036
Joined: Fri Jan 14, 2005 3:56 pm
Contact:

Re: Border tracing Mandelbrot generator for the Beeb

Postby SarahWalker » Sat Oct 29, 2016 5:15 pm

litwr wrote:BTW I would like to have a full throttle key for B-em...

Page Up does this.

litwr
Posts: 184
Joined: Sun Jun 12, 2016 8:44 am

Re: Border tracing Mandelbrot generator for the Beeb

Postby litwr » Sat Oct 29, 2016 5:32 pm

SarahWalker wrote:Page Up does this.
Thanks. I have missed this. However it is useful to have a toggle key for a long computations like Mandelbrot.

User avatar
SimonSideburns
Posts: 251
Joined: Mon Aug 26, 2013 8:09 pm
Location: Purbrook, Hampshire
Contact:

Re: Border tracing Mandelbrot generator for the Beeb

Postby SimonSideburns » Sat Oct 29, 2016 8:30 pm

Funnily enough, I have been writing the Mandelbrot in a BASIC program on the ZX Spectrum recently as I am a member of a facebook group called BASIC on the ZX Spectrum.

My code includes a zoom rectangle, three dithering methods (to avoid the famous Spectrum colour clash it is in monochrome) - simple alternating black/white iteration bands, black, checkerboard, white, opposite checkerboard,black (and so on), or smoothed between bands alternating from solid black to solid white, then back to solid black but with dithering in between. Only thing I haven't included is saving and loading of locations.

Needless to say, the code is pretty slow, but it has progressed as far as I wish it to for now. I tweak now and then to add another bit of functionality.

Does anyone wish to see the code and/or samples of the generated fractals. I'm not sure if links to the images on facebook's servers would display inline in the post, so here's hoping:

Image

Image

Image

Image

Those are a few samples of the output. Here's the code:

Code: Select all

10 REM \{vi}Hires Mandelbrot\{vn}
20 REM \{vi}\*2016 Simon Ferre'\{vn}
30 RANDOMIZE
40 LET fg=0: LET bg=7
50 BORDER 7: PAPER bg: INK fg: CLS : LET k$=""
60 LET l=LN 2
70 LET dither=0
80 LET smooth=1
90 LET iter=64
100 LET width=4
110 LET height=2.75
120 LET bailout=64
130 LET b=LN (LN (bailout))
140 LET xstart=width/2-width
150 LET ystart=height/2-height
160 LET xstep=width/255
170 LET ystep=height/175
180 LET res=8
190 LET k$="": IF INKEY$<>"" THEN GO TO 190
200 FOR y=0 TO 175 STEP res
210 PRINT #0;AT 0,0;"\{vi}z\{vn}oom \{vi}i\{vn}ters \{vi}d\{vn}ither \{vi}s\{vn}mooth \{vi}b\{vn}ailout";AT 1,0;"\{vi}f\{vn}/g \{vi}b\{vn}/g cols"
220 IF res=1 THEN PRINT #0;AT 1,28;INT (y/1.75);"%";
230 FOR x=0 TO 255 STEP res
240 REM \{vi}Iterate\{vn}
250 IF POINT (x,y) THEN GO TO 640
260 LET i=1: LET it=1: REM Iter count and Iter type
270 LET zr=xstart+x*xstep: LET JuliaR=zr
280 LET zi=ystart+y*ystep: LET JuliaI=zi
290 REM \{vi}Inner iterations\{vn}
300 IF k$="" THEN LET k$=INKEY$: IF k$="" THEN GO TO 380
310 IF k$="d" THEN INPUT "Dither (y/n)? "; LINE k$: LET dither=0+(1 AND k$="y"): CLS : LET k$="": GO TO 180
320 IF k$="s" THEN INPUT "Smooth (y/n)? "; LINE k$: LET smooth=0+(1 AND k$="y"): CLS : LET k$="": GO TO 180
330 IF k$="f" THEN LET fg=fg+1: LET fg=fg-8*(fg=8): LET fg=fg+1*(fg=bg): LET fg=fg-8*(fg=8): GO SUB 1020: LET k$=""
340 IF k$="b" THEN LET bg=bg+1: LET bg=bg-8*(bg=8): LET bg=bg+1*(bg=fg): LET bg=bg-8*(bg=8): GO SUB 1020: LET k$=""
350 IF k$="z" THEN GO TO 670
360 IF k$="i" THEN INPUT ("Old=";iter;", new (same=cancel)=");niter: IF niter<>iter THEN CLS : LET k$="": LET iter=niter: GO TO 180
370 LET k$=""
380 LET zrsqr=zr*zr
390 LET zisqr=zi*zi
400 IF zisqr+zrsqr>bailout OR i>=iter THEN GO TO 450
410 LET zi=zr*zi*2+JuliaI
420 LET zr=zrsqr-zisqr+JuliaR
430 LET i=i+1: LET it=it+1: IF it=5 THEN LET it=1
440 GO TO 290
450 REM \{vi}Escaped or max iter\{vn}
460 IF i>=iter THEN LET it=5
470 IF dither THEN GO TO 580
480 IF NOT smooth THEN GO TO 550
490 REM Smooth colouring method
500 IF it=5 THEN GO TO 640: REM no plot for inside points
510 LET s=(b-LN ABS (LN ABS (SQR ABS (zisqr+zrsqr))))/l
520 IF it=1 OR it=3 THEN IF s<RND THEN PLOT x,y: REM band from white to black
530 IF it=2 OR it=4 THEN IF s>RND THEN PLOT x,y: REM band from black to white
540 GO TO 640
550 REM Alternating black/white method
560 IF i/2=INT (i/2) THEN PLOT x,y
570 GO TO 640
580 REM Checkerboard dithering method
590 IF it=1 OR it=5 THEN GO TO 640
600 IF it=3 THEN PLOT x,y: GO TO 640
610 LET p=0: LET xy=x+y: IF xy/2=INT (xy/2) THEN LET p=1
620 IF it=2 THEN PLOT INVERSE NOT p;x,y
630 IF it=4 THEN PLOT INVERSE p;x,y
640 NEXT x
650 NEXT y
660 LET res=res/2: IF res>=1 THEN GO TO 200
670 LET xl=0: LET xr=255: LET yb=0: LET yt=175: LET ratio=175/255
680 PRINT #0;AT 0,0;"                                 "
690 PRINT #0;AT 0,0;"\{vi}zZ\{vn}oom, \{vi}Enter\{vn}=zoom in \{vi}f\{vn}g/\{vi}b\{vn}g cols": PRINT #0;AT 1,0;"\{vi}QAOP\{vn} move box, \{vi}Delete\{vn}=zoom out"
700 PLOT OVER 1;xl,yb: DRAW OVER 1;xr-xl,0: DRAW OVER 1;0,yt-yb: DRAW OVER 1;-(xr-xl),0: DRAW OVER 1;0,-(yt-yb): PLOT OVER 1;xl,yb
710 LET k$=INKEY$: IF k$="" THEN GO TO 710
720 PLOT OVER 1;xl,yb: DRAW OVER 1;xr-xl,0: DRAW OVER 1;0,yt-yb: DRAW OVER 1;-(xr-xl),0: DRAW OVER 1;0,-(yt-yb): PLOT OVER 1;xl,yb
730 IF k$="f" THEN LET fg=fg+1: LET fg=fg-8*(fg=8): LET fg=fg+1*(fg=bg): LET fg=fg-8*(fg=8): GO SUB 1020: LET k$=""
740 IF k$="b" THEN LET bg=bg+1: LET bg=bg-8*(bg=8): LET bg=bg+1*(bg=fg): LET bg=bg-8*(bg=8): GO SUB 1020: LET k$=""
750 IF k$="z" AND xr-xl>16 THEN LET xl=xl+2: LET xr=xr-2: LET yb=yb+2*ratio: LET yt=yt-2*ratio: GO TO 700
760 IF k$<>"Z" THEN GO TO 820
770 IF xl>1 THEN LET xl=xl-2: LET xr=xr+2: LET yb=yb-2*ratio: LET yt=yt+2*ratio
780 IF xl<0 THEN LET o=0-xl: LET xl=0: IF xr+o<=255 THEN LET xr=xr+o
790 IF xr>255 THEN LET o=xr-255: LET xr=255: IF xl-o>=0 THEN LET xl=xl-o
800 IF yb<0 THEN LET o=0-yb: LET yb=0: IF yt+o<=175 THEN LET yt=yt+o
810 IF yt>175 THEN LET o=yt-175: LET yt=175: IF yb-o>=0 THEN LET yb=yb-o
820 IF k$="o" AND xl>2 THEN LET xl=xl-2: LET xr=xr-2
830 IF k$="p" AND xr<253 THEN LET xl=xl+2: LET xr=xr+2
840 IF k$="q" AND yt<173 THEN LET yb=yb+2: LET yt=yt+2
850 IF k$="a" AND yb>2 THEN LET yb=yb-2: LET yt=yt-2
860 IF k$<>CHR$ 13 THEN GO TO 930
870 REM set new offsets and redraw
880 LET width=(xr-xl)*xstep
890 LET height=(yt-yb)*ystep
900 LET xstart=xstart+xl*xstep
910 LET ystart=ystart+yb*ystep
920 CLS : LET k$="": GO TO 160
930 IF k$<>CHR$ 12 THEN GO TO 1000
940 REM Zoom out
950 LET width=width*256/(xr-xl)
960 LET height=height*176/(yt-yb)
970 LET xstart=xstart-xl*xstep
980 LET ystart=ystart-yb*ystep
990 CLS : LET k$="": GO TO 160
1000 IF k$="0" THEN PAUSE 0
1010 GO TO 700
1020 REM colours
1030 PAPER bg: INK fg: FOR n=0 TO 21: PRINT AT n,0; OVER 1; INK fg; PAPER bg;TAB 31;" ";: NEXT n: RETURN


The codes like \{vi} or \{vn} are ZX BASIC codes for setting inverse video or normal video, and \* (in line 20) is the copyright character, so can safely be ignored. There is a programming environment that runs in Windows, called BasinC which allows one window to edit code, another to see the output (e.g. an emulator) and is very complete. Installing it and pasting in my code is sufficient to run the program. There is a turbo mode within BasinC which activates on a press of the F1 key (which makes program execution in this case almost bearable).

The whole code is a bit spaghetti-like and could be improved, but Sinclair BASIC doesn't have PROCedures and REPEAT UNTIL etc.
I'm writing a game where you can change your character from a Wizard to a monkey to a cat.

Well, Imogen that!


Return to “software: other”

Who is online

Users browsing this forum: No registered users and 3 guests