CPCWiki forum

General Category => Demos => Topic started by: litwr on 06:54, 05 October 16

Title: Mandelbrot with Amstrad
Post by: litwr on 06:54, 05 October 16
The idea was imported from http://cbmandelbrot.blogspot.ru/ (http://cbmandelbrot.blogspot.ru/)  :D
I have just made a conversion for Amstrad CPC.
[attachimg=1]
Amstrad CPC ROM Basic makes it for 5 hours 27 minutes and about 12 seconds.  It is much faster than any Commodore of 80s.
I'm aware about http://www.cpcwiki.eu/forum/programming/mandelbrot-in-one-basic-line/ (http://www.cpcwiki.eu/forum/programming/mandelbrot-in-one-basic-line/) but  this is a bit different.
BTW it is also a thread at C+4 forum about this subject, it also mentions the Fibonacci Sunflower demo - http://plus4world.powweb.com/forum/32712 (http://plus4world.powweb.com/forum/32712)
Commodore Basic original text

   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$

Amstrad CPC Basic text (I am not sure that it can't be made faster.)

   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 1:time0=TIME
   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 s%+s%,400-t%-t%,1
   19 IF s%<2 or t%<2 THEN 28
   20 IF TEST(s%+s%-2,402-t%-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 s%+s%-2,402-t%-t%,0
   28 NEXT s%:z=a:a=b:b=c:c=z:NEXT:clk=(TIME-time0)/300:hours=int(clk/3600):mins=int(clk/60-hours*60)
   29 a$=INKEY$:IF a$="" THEN 29
   30 CLS:PRINT hours;mins;int(clk-hours*3600-mins*60)
Title: Re: Mandelbrot with Amstrad
Post by: robcfg on 09:17, 05 October 16
Nice use of mode 2!


I would suggest using dither to create the illusion of a third color to improve the result.


I did that on the Dragon and the result is quite good!


[attachimg=1]
Title: Re: Mandelbrot with Amstrad
Post by: mr_lou on 14:49, 05 October 16
How long does it take to render?
I made a Mandelbrott BASIC listing as a kid too, and as far as I remember it took the CPC 4 days to draw the whole thing.
May not have been the smartest listing in the world though.
Title: Re: Mandelbrot with Amstrad
Post by: HAL6128 on 19:42, 05 October 16
Oh yeah! I remember myself too. When I programmed as a kid my listing it took the whole night and half of the day for rendering. I started the program before I had gone to bed and covered the monitor to prevent glimmering the whole room. After had been coming back from school the picture was finished. :)
Title: Re: Mandelbrot with Amstrad
Post by: litwr on 20:52, 05 October 16
Quote from: robcfg on 09:17, 05 October 16
I did that on the Dragon and the result is quite good!
Dragon 32/64?  The result is impressive.  It is interesting to look at the code.  Is it Basic?
Title: Re: Mandelbrot with Amstrad
Post by: SRS on 21:20, 05 October 16
Well done :)

But: why monocolored in MODE 1 ?

I don't get why the very big (and slow) arrays are needed ? Maybe to late for me [attach=2] today ;)

Using 16 iterations per pixel, some y-symmetrics, four colors and saving 30 "empty" pixels left and right
a color mandel in 32 minutes.

using

10 MODE 1:time0=TIME
20 maxIteration = 16
30 px=70:py=0
40 FOR x0 = -1.6 TO 0.6 STEP 0.01
50 FOR y0 = -1 TO 0 STEP 0.01
60 x=0:y=0:iteration=0
70 x2=x*x:y2=y*y
80 WHILE (x2 + y2 <= (4) AND iteration < maxIteration)
90 xtemp = x2 - y2 + x0
100 y = 2 * x * y + y0
110 x = xtemp:iteration = iteration + 1
120 x2=x*x:y2=y*y:WEND
130 IF iteration<>maxIteration THEN c=iteration\4 ELSE c=0:GOTO 150
140 PLOT px,py,c:PLOT px,400-py,c
150 py=py+2
160 NEXT
170 px=px+2:py=0
180 NEXT:clk=(TIME-time0)/300:hours=INT(clk/3600):mins=INT(clk/60-hours*60)
190 a$=INKEY$:IF a$="" THEN 190
200 CLS:PRINT hours;mins;INT(clk-hours*3600-mins*60)

Title: Re: Mandelbrot with Amstrad
Post by: robcfg on 22:00, 05 October 16
Quote from: litwr on 20:52, 05 October 16
Dragon 32/64?  The result is impressive.  It is interesting to look at the code.  Is it Basic?


Sure!


Here (http://archive.worldofdragon.org/index.php?title=K3_Fractals) you have my source code (the ASC file) and several nice screenshots.


It's a bit longer than the original code to support multiple screen resolutions, colors and dither (very much needed).


If you use the dither on mode 1, you should get pretty nice results.
Title: Re: Mandelbrot with Amstrad
Post by: SRS on 14:05, 06 October 16
@robcfg (http://www.cpcwiki.eu/forum/index.php?action=profile;u=4):

Try this (ugly colors, I know)

10 REM K3 FRACTALS FOR THE DRAGON COMPUTER
20 REM BY ROBCFG WITH HELP OF HABI AND SYX
25 REM Patched to AMSTRAD CPC by SRS
30 GOSUB 430
40 FT=0:SM=0:PA=0:FX=0:F2=0:FY=0:NI=0:MI=0:C=0:X=0:Y=0
50 VM=&c000:RX=320:RY=400:MX=0:MY=0:DX=0:DY=0
60 PRINT"PLEASE CHOOSE A FRACTAL TYPE:":PRINT
70 PRINT"<1> MANDELBROT"
80 PRINT"<2> JULIA":PRINT
90 INPUT"FRACTAL TYPE";FT
100 GOSUB 430
110 PRINT "PLEASE CHOOSE A SCREEN MODE:":PRINT
120 PRINT"<1> 320X200 4 COLORS"
130 PRINT"<2> 640X200 2 COLORS":PRINT
140 INPUT"SCREEN MODE";SM:SM=SM+2:IF SM=4 THEN RX=640
150 GOSUB 430
160 PRINT"PLEASE CHOOSE A COLOR PALETTE:":PRINT
170 IF SM=4 THEN GOTO 230
180 REM -- 4 COLOR PALETTE --
190 PRINT"<1> RED,GREEN,YELLOW,BLUE"
200 PRINT"<2> ORANGE,BUFF,CYAN,MAGENTA":PRINT
210 GOTO 260
220 REM -- 2 COLOR PALETTE --
230 PRINT"<1> GREEN,BLACK"
240 PRINT"<2> BUFF,BLACK"
250 IF SM<>4 THEN PRINT ELSE PRINT"<3> NTSC ARTIFACTS":PRINT
260 INPUT"COLOR PALETTE";PA:PA=PA-1:PRINT
270 GOSUB 430
280 IF FT=1 THEN PRINT"FOR FULL MANDELBROT USE":PRINT"X1=-2.4,X2=1.04,Y1=-1.3"
290 IF FT=2 THEN PRINT"FOR FULL JULIA USE":PRINT"X1=-1.666,X2=1.666,Y1=-1.25"
300 PRINT
310 PRINT"ENTER X1 COORDINATE:":INPUT FX
320 PRINT"ENTER X2 COORDINATE:":INPUT F2
330 PRINT"ENTER Y1 COORDINATE:":INPUT FY
340 PRINT"ENTER ITERATIONS:":INPUT NI:MI=NI-1:GOSUB 430
350 DX=F2-FX:DY=DX*(RY/RX):IF SM=3 THEN DY=DY/2
360 PRINT:PRINT"WHEN THE FRACTAL IS FINISHED,"
370 PRINT"PRESS A KEY TO CONTINUE.":PRINT
380 PRINT"YOU'LL BE ASKED TO SAVE":PRINT"YOUR IMAGE."
390 PRINT:PRINT"PRESS A KEY TO START.":GOSUB 460
400 MODE SM-2:IF PA=0 THEN ink 0,6:ink 1,18:ink 2,26:ink 3,1 ELSE ink 0,12:ink 1,13:ink 2,4:ink 3,16
410 CLS
420 ON FT GOTO 470,820
430 REM -- CLEAR SCREEN AND SHOW BANNER --
440 CLS:PRINT"      * K3 FRACTALS V1.0 *":PRINT:RETURN
450 REM -- WAIT FOR A KEY PRESS
460 IF INKEY$="" THEN GOTO 460 ELSE RETURN
470 REM -- MANDELBROT --
480 E=FY
490 Y=0:REM FOR Y=0 TO MY
500 D=FX
510 X=0:REM FOR X=0 TO MX
520 Z=0:I=0:A=0:z2=0:i2=0
530 S=(Z2)-(I2)+D:R=(2*I*Z)+E:Z=S:I=R:A=A+1:z2=z*z:i2=i*i
540 IF A<MI AND (Z2+I2)<4 THEN GOTO 530
550 IF SM=4 THEN C=0 ELSE C=3
560 IF A=MI THEN GOTO 760:REM EARLY OUT
570 IF SM=3 THEN GOTO 670:REM 4 COLOR PALETTE
580 IF PA=2 THEN GOTO 610
590 IF (A AND 1)=0 THEN GOSUB 1190 ELSE GOSUB 1210
600 GOTO 760
610 J=A AND 3
620 on J GOSUB 1190,1240,1190,1270
660 GOTO 760
670 K=(A/8)-INT(A/8)
680 J=K*8
690 ON J GOSUB 1300,1330,1350,1380,1400,1430,1450
760 IF SM=3 THEN plot X*2,Y,C ELSE plot X,Y,C
770 D=D+DX/RX:REM D=D+0.013437
780 X=X+1:IF X<RX THEN GOTO 520:REM NEXT X
790 E=E+DY/RY:REM E=E+0.013541
800 Y=Y+2:IF Y<RY THEN GOTO 500:REM NEXT Y
810 GOSUB 450:GOTO 1480
820 REM -- JULIA --
830 CR=-0.4:CI=0.6:MX=RX-1:MY=RY-1
840 E=FY
850 Y=0:REM FOR Y=0 TO MY
860 D=FX
870 X=0:REM FOR X=0 TO MX
880 Z=D:I=E:A=0:z2=0:i2=0
890 S=(Z2)-(I2)+CR:R=(2*I*Z)+CI:Z=S:I=R:A=A+1:i2=i*i:z2=z*z
900 IF A<MI AND (Z2+I2)<4 THEN GOTO 890
910 IF SM=4 THEN C=0 ELSE C=3
920 IF A=MI THEN GOTO 1120:REM EARLY OUT
930 IF SM=3 THEN GOTO 1030
940 IF PA=2 THEN GOTO 970
950 IF (A AND 1)=0 THEN GOSUB 1190 ELSE GOSUB 1210
960 GOTO 1120
970 J=A AND 3
980 ON J GOSUB 1190,1240,1190,1270
1020 GOTO 1120
1030 K=(A/8)-INT(A/8)
1040 J=K*8
1050 ON J GOSUB 1300,1330,1350,1380,1400,1430,1450
1120 IF SM=3 THEN plot X*2,Y,C ELSE plot X,Y,C
1130 D=D+DX/RX
1140 X=X+1:IF X<RX THEN GOTO 880:REM NEXT X
1150 E=E+DY/RY
1160 Y=Y+2:IF Y<RY THEN GOTO 860:REM NEXT Y
1170 GOSUB 450:GOTO 1480
1180 REM -- COLOR SELECTION AND DITHERING --
1190 REM -- WHITE STRIP --
1200 C=1:RETURN
1210 REM -- WHITE-BLACK PATTERN --
1220 IF (X AND 1)=(Y AND 1) THEN C=1
1230 RETURN
1240 REM -- WHITE-BLACK NTSC LINES --
1250 IF (X AND 1)=0 THEN C=1
1260 RETURN
1270 REM -- BLACK-WHITE NTSC LINES --
1280 IF (X AND 1)<>0 THEN C=1
1290 RETURN
1300 REM -- GREEN-YELLOW PATTERN --
1310 IF (X AND 1)=(Y AND 1) THEN C=3 ELSE C=1
1320 RETURN
1330 REM -- YELLOW --
1340 C=1:RETURN
1350 REM -- YELLOW-RED PATTERN --
1360 IF (X AND 1)=(Y AND 1) THEN C=1 ELSE C=2
1370 RETURN
1380 REM -- RED --
1390 C=2:RETURN
1400 REM -- RED-BLUE PATTERN --
1410 IF (X AND 1)=(Y AND 1) THEN C=2 ELSE C=0
1420 RETURN
1430 REM -- BLUE --
1440 C=0:RETURN
1450 REM -- BLUE-GREEN PATTERN --
1460 IF (X AND 1)=(Y AND 1) THEN C=0 ELSE C=3
1470 RETURN
1480 REM -- SAVE IMAGE MENU --
1600 IF FT=1 THEN SAVE"MANDELBR",b,VM,&3fff,VM ELSE SAVE"JULIA",b,VM,&3fff,VM
1610 GOTO 10


[attachimg=1]
Title: Re: Mandelbrot with Amstrad
Post by: robcfg on 16:32, 20 October 16
I hope you didn't think I forgot about you  ;)


I managed to fix the code and Mandelbrot renders quite good on mode 1 and mode 2:


[attach=2][attach=3]


Here's the code:
10 REM K3 FRACTALS FOR THE DRAGON COMPUTER
20 REM BY ROBCFG WITH HELP OF HABI AND SYX
25 REM Patched to AMSTRAD CPC by SRS
30 GOSUB 430
40 FT=0:SM=0:PA=0:FX=0:F2=0:FY=0:NI=0:MI=0:C=0:X=0:Y=0
50 VM=&c000:RX=320:RY=200:MX=0:MY=0:DX=0:DY=0
60 PRINT"PLEASE CHOOSE A FRACTAL TYPE:":PRINT
70 PRINT"<1> MANDELBROT"
80 PRINT"<2> JULIA":PRINT
90 INPUT"FRACTAL TYPE";FT
100 GOSUB 430
110 PRINT "PLEASE CHOOSE A SCREEN MODE:":PRINT
120 PRINT"<1> 320X200 4 COLORS"
130 PRINT"<2> 640X200 2 COLORS":PRINT
140 INPUT"SCREEN MODE";SM:SM=SM+2:IF SM=4 THEN RX=640
150 GOSUB 430
160 PRINT"PLEASE CHOOSE A COLOR PALETTE:":PRINT
170 IF SM=4 THEN GOTO 230
180 REM -- 4 COLOR PALETTE --
190 PRINT"<1> RED,GREEN,YELLOW,BLUE"
200 PRINT"<2> ORANGE,BUFF,CYAN,MAGENTA":PRINT
210 GOTO 260
220 REM -- 2 COLOR PALETTE --
230 PRINT"<1> GREEN,BLACK"
240 PRINT"<2> BUFF,BLACK"
250 IF SM<>4 THEN PRINT ELSE PRINT"<3> NTSC ARTIFACTS":PRINT
260 INPUT"COLOR PALETTE";PA:PA=PA-1:PRINT
270 GOSUB 430
280 IF FT=1 THEN PRINT"FOR FULL MANDELBROT USE":PRINT"X1=-2.4,X2=1.04,Y1=-1.3"
290 IF FT=2 THEN PRINT"FOR FULL JULIA USE":PRINT"X1=-1.666,X2=1.666,Y1=-1.25"
300 PRINT
310 PRINT"ENTER X1 COORDINATE:":INPUT FX
320 PRINT"ENTER X2 COORDINATE:":INPUT F2
330 PRINT"ENTER Y1 COORDINATE:":INPUT FY
340 PRINT"ENTER ITERATIONS:":INPUT NI:MI=NI-1:GOSUB 430
350 DX=F2-FX:DY=DX*(RY/RX)*2:IF SM=3 THEN DY=DY/2
360 PRINT:PRINT"WHEN THE FRACTAL IS FINISHED,"
370 PRINT"PRESS A KEY TO CONTINUE.":PRINT
380 PRINT"YOU'LL BE ASKED TO SAVE":PRINT"YOUR IMAGE."
390 PRINT:PRINT"PRESS A KEY TO START.":GOSUB 460
400 MODE SM-2:IF PA=0 THEN ink 0,6:ink 1,18:ink 2,26:ink 3,1 ELSE ink 0,12:ink 1,13:ink 2,4:ink 3,16
410 CLS
420 ON FT GOTO 470,820
430 REM -- CLEAR SCREEN AND SHOW BANNER --
440 CLS:PRINT"      * K3 FRACTALS V1.0 *":PRINT:RETURN
450 REM -- WAIT FOR A KEY PRESS
460 IF INKEY$="" THEN GOTO 460 ELSE RETURN
470 REM -- MANDELBROT --
480 E=FY
490 Y=0:REM FOR Y=0 TO MY
500 D=FX
510 X=0:REM FOR X=0 TO MX
520 Z=0:I=0:A=0:z2=0:i2=0
530 S=(Z2)-(I2)+D:R=(2*I*Z)+E:Z=S:I=R:A=A+1:z2=z*z:i2=i*i
540 IF A<MI AND (Z2+I2)<4 THEN GOTO 530
550 IF SM=4 THEN C=0 ELSE C=3
560 IF A=MI THEN GOTO 760:REM EARLY OUT
570 IF SM=3 THEN GOTO 670:REM 4 COLOR PALETTE
580 IF PA=2 THEN GOTO 610
590 IF (A AND 1)=0 THEN GOSUB 1190 ELSE GOSUB 1210
600 GOTO 760
610 J=A AND 3
620 on J GOSUB 1190,1240,1190,1270
660 GOTO 760
670 K=(A/8)-INT(A/8)
680 J=K*8
690 ON J GOSUB 1300,1330,1350,1380,1400,1430,1450
760 IF SM=3 THEN plot X*2,Y*2,C ELSE plot X,Y*2,C
770 D=D+DX/RX:REM D=D+0.013437
780 X=X+1:IF X<RX THEN GOTO 520:REM NEXT X
790 E=E+DY/RY:REM E=E+0.013541
800 Y=Y+1:IF Y<RY THEN GOTO 500:REM NEXT Y
810 GOSUB 450:GOTO 1480
820 REM -- JULIA --
830 CR=-0.4:CI=0.6:MX=RX-1:MY=RY-1
840 E=FY
850 Y=0:REM FOR Y=0 TO MY
860 D=FX
870 X=0:REM FOR X=0 TO MX
880 Z=D:I=E:A=0:z2=0:i2=0
890 S=(Z2)-(I2)+CR:R=(2*I*Z)+CI:Z=S:I=R:A=A+1:i2=i*i:z2=z*z
900 IF A<MI AND (Z2+I2)<4 THEN GOTO 890
910 IF SM=4 THEN C=0 ELSE C=3
920 IF A=MI THEN GOTO 1120:REM EARLY OUT
930 IF SM=3 THEN GOTO 1030
940 IF PA=2 THEN GOTO 970
950 IF (A AND 1)=0 THEN GOSUB 1190 ELSE GOSUB 1210
960 GOTO 1120
970 J=A AND 3
980 ON J GOSUB 1190,1240,1190,1270
1020 GOTO 1120
1030 K=(A/8)-INT(A/8)
1040 J=K*8
1050 ON J GOSUB 1300,1330,1350,1380,1400,1430,1450
1120 IF SM=3 THEN plot X*2,Y*2,C ELSE plot X,Y*2,C
1130 D=D+DX/RX
1140 X=X+1:IF X<RX THEN GOTO 880:REM NEXT X
1150 E=E+DY/RY
1160 Y=Y+1:IF Y<RY THEN GOTO 860:REM NEXT Y
1170 GOSUB 450:GOTO 1480
1180 REM -- COLOR SELECTION AND DITHERING --
1190 REM -- WHITE STRIP --
1200 C=1:RETURN
1210 REM -- WHITE-BLACK PATTERN --
1220 IF (X AND 1)=(Y AND 1) THEN C=1
1230 RETURN
1240 REM -- WHITE-BLACK NTSC LINES --
1250 IF (X AND 1)=0 THEN C=1
1260 RETURN
1270 REM -- BLACK-WHITE NTSC LINES --
1280 IF (X AND 1)<>0 THEN C=1
1290 RETURN
1300 REM -- GREEN-YELLOW PATTERN --
1310 IF (X AND 1)=(Y AND 1) THEN C=3 ELSE C=1
1320 RETURN
1330 REM -- YELLOW --
1340 C=1:RETURN
1350 REM -- YELLOW-RED PATTERN --
1360 IF (X AND 1)=(Y AND 1) THEN C=1 ELSE C=2
1370 RETURN
1380 REM -- RED --
1390 C=2:RETURN
1400 REM -- RED-BLUE PATTERN --
1410 IF (X AND 1)=(Y AND 1) THEN C=2 ELSE C=0
1420 RETURN
1430 REM -- BLUE --
1440 C=0:RETURN
1450 REM -- BLUE-GREEN PATTERN --
1460 IF (X AND 1)=(Y AND 1) THEN C=0 ELSE C=3
1470 RETURN
1480 REM -- SAVE IMAGE MENU --
1600 IF FT=1 THEN SAVE"MANDELBR",b,VM,&3fff,VM ELSE SAVE"JULIA",b,VM,&3fff,VM
1610 GOTO 10



Julia render seems to work ok, but there is a mistake in the formula computation. I'll try to fix it too.
Title: Re: Mandelbrot with Amstrad
Post by: SRS on 19:58, 20 October 16
Very nice :)

And it uses a new MODE for CPC - the CGA1.

C
olorfulGrafikAdvanced Mode 1 with 320x200 Pixel in 8 Colors :)  instead of 4. Ha ! In BASIC.

Title: Re: Mandelbrot with Amstrad
Post by: robcfg on 14:37, 21 October 16
Fixed Julia!


[attach=2][attach=3]


The Z*Z optimization is nice but you left the z2 and i2 vars set to 0 instead of the right values  ;)


Here's the code:


10 REM K3 FRACTALS FOR THE DRAGON COMPUTER
20 REM BY ROBCFG WITH HELP OF HABI AND SYX
25 REM Patched to AMSTRAD CPC by SRS
30 GOSUB 430
40 FT=0:SM=0:PA=0:FX=0:F2=0:FY=0:NI=0:MI=0:C=0:X=0:Y=0
50 VM=&c000:RX=320:RY=200:MX=0:MY=0:DX=0:DY=0
60 PRINT"PLEASE CHOOSE A FRACTAL TYPE:":PRINT
70 PRINT"<1> MANDELBROT"
80 PRINT"<2> JULIA":PRINT
90 INPUT"FRACTAL TYPE";FT
100 GOSUB 430
110 PRINT "PLEASE CHOOSE A SCREEN MODE:":PRINT
120 PRINT"<1> 320X200 4 COLORS"
130 PRINT"<2> 640X200 2 COLORS":PRINT
140 INPUT"SCREEN MODE";SM:SM=SM+2:IF SM=4 THEN RX=640
150 GOSUB 430
160 PRINT"PLEASE CHOOSE A COLOR PALETTE:":PRINT
170 IF SM=4 THEN GOTO 230
180 REM -- 4 COLOR PALETTE --
190 PRINT"<1> RED,GREEN,YELLOW,BLUE"
200 PRINT"<2> ORANGE,BUFF,CYAN,MAGENTA":PRINT
210 GOTO 260
220 REM -- 2 COLOR PALETTE --
230 PRINT"<1> GREEN,BLACK"
240 PRINT"<2> BUFF,BLACK"
250 IF SM<>4 THEN PRINT ELSE PRINT"<3> NTSC ARTIFACTS":PRINT
260 INPUT"COLOR PALETTE";PA:PA=PA-1:PRINT
270 GOSUB 430
280 IF FT=1 THEN PRINT"FOR FULL MANDELBROT USE":PRINT"X1=-2.4,X2=1.04,Y1=-1.3"
290 IF FT=2 THEN PRINT"FOR FULL JULIA USE":PRINT"X1=-1.666,X2=1.666,Y1=-1.25"
300 PRINT
310 PRINT"ENTER X1 COORDINATE:":INPUT FX
320 PRINT"ENTER X2 COORDINATE:":INPUT F2
330 PRINT"ENTER Y1 COORDINATE:":INPUT FY
340 PRINT"ENTER ITERATIONS:":INPUT NI:MI=NI-1:GOSUB 430
350 DX=F2-FX:DY=DX*(RY/RX)*2:IF SM=3 THEN DY=DY/2
360 PRINT:PRINT"WHEN THE FRACTAL IS FINISHED,"
370 PRINT"PRESS A KEY TO CONTINUE.":PRINT
380 PRINT"YOU'LL BE ASKED TO SAVE":PRINT"YOUR IMAGE."
390 PRINT:PRINT"PRESS A KEY TO START.":GOSUB 460
400 MODE SM-2:IF PA=0 THEN ink 0,6:ink 1,18:ink 2,26:ink 3,1 ELSE ink 0,12:ink 1,13:ink 2,4:ink 3,16
410 CLS
420 ON FT GOTO 470,820
430 REM -- CLEAR SCREEN AND SHOW BANNER --
440 CLS:PRINT"      * K3 FRACTALS V1.0 *":PRINT:RETURN
450 REM -- WAIT FOR A KEY PRESS
460 IF INKEY$="" THEN GOTO 460 ELSE RETURN
470 REM -- MANDELBROT --
480 E=FY
490 Y=0:REM FOR Y=0 TO MY
500 D=FX
510 X=0:REM FOR X=0 TO MX
520 Z=0:I=0:A=0:z2=0:i2=0
530 S=(Z2)-(I2)+D:R=(2*I*Z)+E:Z=S:I=R:A=A+1:z2=z*z:i2=i*i
540 IF A<MI AND (Z2+I2)<4 THEN GOTO 530
550 IF SM=4 THEN C=0 ELSE C=3
560 IF A=MI THEN GOTO 760:REM EARLY OUT
570 IF SM=3 THEN GOTO 670:REM 4 COLOR PALETTE
580 IF PA=2 THEN GOTO 610
590 IF (A AND 1)=0 THEN GOSUB 1190 ELSE GOSUB 1210
600 GOTO 760
610 J=A AND 3
620 on J GOSUB 1190,1240,1190,1270
660 GOTO 760
670 K=(A/8)-INT(A/8)
680 J=K*8
690 ON J GOSUB 1300,1330,1350,1380,1400,1430,1450
760 IF SM=3 THEN plot X*2,Y*2,C ELSE plot X,Y*2,C
770 D=D+DX/RX:REM D=D+0.013437
780 X=X+1:IF X<RX THEN GOTO 520:REM NEXT X
790 E=E+DY/RY:REM E=E+0.013541
800 Y=Y+1:IF Y<RY THEN GOTO 500:REM NEXT Y
810 GOSUB 450:GOTO 1480
820 REM -- JULIA --
830 CR=-0.4:CI=0.6:MX=RX-1:MY=RY-1
840 E=FY
850 Y=0:REM FOR Y=0 TO MY
860 D=FX
870 X=0:REM FOR X=0 TO MX
880 Z=D:I=E:A=0:z2=Z*Z:i2=I*I
890 S=(Z2)-(I2)+CR:R=(2*I*Z)+CI:Z=S:I=R:A=A+1:i2=i*i:z2=z*z
900 IF A<MI AND (Z2+I2)<4 THEN GOTO 890
910 IF SM=4 THEN C=0 ELSE C=3
920 IF A=MI THEN GOTO 1120:REM EARLY OUT
930 IF SM=3 THEN GOTO 1030
940 IF PA=2 THEN GOTO 970
950 IF (A AND 1)=0 THEN GOSUB 1190 ELSE GOSUB 1210
960 GOTO 1120
970 J=A AND 3
980 ON J GOSUB 1190,1240,1190,1270
1020 GOTO 1120
1030 K=(A/8)-INT(A/8)
1040 J=K*8
1050 ON J GOSUB 1300,1330,1350,1380,1400,1430,1450
1120 IF SM=3 THEN plot X*2,Y*2,C ELSE plot X,Y*2,C
1130 D=D+(DX/RX)
1140 X=X+1:IF X<RX THEN GOTO 880:REM NEXT X
1150 E=E+(DY/RY)
1160 Y=Y+1:IF Y<RY THEN GOTO 860:REM NEXT Y
1170 GOSUB 450:GOTO 1480
1180 REM -- COLOR SELECTION AND DITHERING --
1190 REM -- WHITE STRIP --
1200 C=1:RETURN
1210 REM -- WHITE-BLACK PATTERN --
1220 IF (X AND 1)=(Y AND 1) THEN C=1
1230 RETURN
1240 REM -- WHITE-BLACK NTSC LINES --
1250 IF (X AND 1)=0 THEN C=1
1260 RETURN
1270 REM -- BLACK-WHITE NTSC LINES --
1280 IF (X AND 1)<>0 THEN C=1
1290 RETURN
1300 REM -- GREEN-YELLOW PATTERN --
1310 IF (X AND 1)=(Y AND 1) THEN C=3 ELSE C=1
1320 RETURN
1330 REM -- YELLOW --
1340 C=1:RETURN
1350 REM -- YELLOW-RED PATTERN --
1360 IF (X AND 1)=(Y AND 1) THEN C=1 ELSE C=2
1370 RETURN
1380 REM -- RED --
1390 C=2:RETURN
1400 REM -- RED-BLUE PATTERN --
1410 IF (X AND 1)=(Y AND 1) THEN C=2 ELSE C=0
1420 RETURN
1430 REM -- BLUE --
1440 C=0:RETURN
1450 REM -- BLUE-GREEN PATTERN --
1460 IF (X AND 1)=(Y AND 1) THEN C=0 ELSE C=3
1470 RETURN
1480 REM -- SAVE IMAGE MENU --
1600 IF FT=1 THEN SAVE"MANDELBR",b,VM,&3fff,VM ELSE SAVE"JULIA",b,VM,&3fff,VM
1610 GOTO 10



Cheers,
Rob
Title: Re: Mandelbrot with Amstrad
Post by: SRS on 19:04, 21 October 16
;)

P.S.: compiling with FABACOMgives 14k binary but not very much faster.(It uses firmware afaik for floating point calculation so ...)
Title: Re: Mandelbrot with Amstrad
Post by: AMSDOS on 22:26, 21 October 16
Did you want me to try and write something like that up in Pascal Rob?
Title: Re: Mandelbrot with Amstrad
Post by: robcfg on 22:31, 21 October 16
Sure! It should be quite straightforward to translate the code to Pascal and would be nice to see the performance increase.

Isn't it funny that the original code is the Mandelbrot one liner published here, ported to Dragon and back to CPC? :D
Title: Re: Mandelbrot with Amstrad
Post by: AMSDOS on 08:57, 29 October 16
Quote from: robcfg on 22:31, 21 October 16
Sure! It should be quite straightforward to translate the code to Pascal and would be nice to see the performance increase.


Actually, this code has beaten me to a pulp. I don't know how to write it structurally.  :'(


QuoteIsn't it funny that the original code is the Mandelbrot one liner published here, ported to Dragon and back to CPC? :D


Greetings Dragon users.  :)
Title: Re: Mandelbrot with Amstrad
Post by: litwr on 17:00, 01 November 16
I am a bit confused by a fact of impossibility to convert the Basic code from the initial post to Pascal or even modern Basic.  So the modern programming languages lost some power of their ancestors...  RESUME NEXT may also be added to the list of the lost Basic features.
It is curious to have an interactive Mandelbrot builder in ML.  A BBC Micro enthusiast has just made one.  It draws a screen in about 2 minutes.
Title: Re: Mandelbrot with Amstrad
Post by: AMSDOS on 02:08, 05 November 16
Quote from: litwr on 17:00, 01 November 16
I am a bit confused by a fact of impossibility to convert the Basic code from the initial post to Pascal or even modern Basic.  So the modern programming languages lost some power of their ancestors...  RESUME NEXT may also be added to the list of the lost Basic features.


I wouldn't go as far as to say it's impossible, but the problem I'm having here is writing it structurally, it's structurally complicated. Unfortunately this is not the 1st BASIC program I've stumbled over, I have tried to structurally write a Snow Flake Graphical program, unfortunately without any success.


The obvious solution is to throw away the structured principals and surrender to the GOTO command! In BASIC a GOTO can go anywhere, but in Pascal it cannot, labels have to be declared at the beginning of a PROCEDURE and GOTO is restricted to within a PROCEDURE.
Title: Re: Mandelbrot with Amstrad
Post by: SRS on 22:04, 05 November 16
@AMSDOS (http://www.cpcwiki.eu/forum/index.php?action=profile;u=330): maybe use this and pimp it colourwise ?

http://cirsovius.de/CPM/Projekte/Artikel/Grafik/Mandelbrot/ApfelMann.html

or this

https://rosettacode.org/wiki/Mandelbrot_set#Pascal

or this

https://rosettacode.org/wiki/Mandelbrot_set#Z80_Assembly

;)
Title: Re: Mandelbrot with Amstrad
Post by: AMSDOS on 08:14, 06 November 16

Thanks


I've done some hard work on the BASIC version to produce a Pascal version which looks similar to that Pascal Example on Rosetta code, but I haven't been able to created that rendered effect to make it look more colourful.


The problem I think is in Turbo Pascal you can have an "arithmetic and" or a "logical and". Locomotive BASIC also allows arithmetic or logical and to produce that result. Hisoft Pascal on the other hand only allows "logical and", but it maybe possible to code some inline m/c function, though I'm unsure.


In assembly there is:


and <data> - which takes what's in the Accumulator and the data & puts the result in the Accumulator
and reg - as above, but involves the specified register and the Accumulator and puts the result in the Accumulator.
and (hl) - which takes the contents of HL with the contents of the Accumulator and returns a result in the Accumulator.


In the BASIC something like this is carried out:


IF (x and 1)=(y and 1) THEN C=3 ELSE C=1


unfortunately I'm unsure how that can be applied in Hisoft Pascal. x & y are Integers, so I'm wondering if the arithmetic and operates differently from the Assembly AND instructions?
Title: Re: Mandelbrot with Amstrad
Post by: robcfg on 23:37, 06 November 16
You can try to use the modulus operation to achieve the result of:
QuoteIF (x and 1)=(y and 1) THEN C=3 ELSE C=1


That line basically says that if x and y are both even, then the color is 3, 1 otherwise.


In C++ it would be:
Quoteif( (x%2 == 1) && (y%2 == 1) )
    c = 3;
else
    c = 1;


Using arithmetic and would be faster than modulus though.
Title: Re: Mandelbrot with Amstrad
Post by: AMSDOS on 00:15, 07 November 16
Hmm ok. There's a function in pascal called ODD that can be used in a similar fashion I think.
Title: Re: Mandelbrot with Amstrad
Post by: AMSDOS on 12:08, 07 November 16
Okay so earlier I went through the BASIC Mandelbrot which was posted in here, but I've stripped it right back, no menu, no Julia Set and just a set bunch of values, which gave me this structured routine:




40 FT=1:SM=3:PA=0:FX=0:F2=0:FY=0:NI=0:MI=0:C=0:X=0:Y=0
50 RX=320:RY=200:DX=0:DY=0
60 MODE 1:INK 0,6:INK 1,18:INK 2,26:INK 3,1
70 FX=-2.4:F2=1.04:FY=-1.3:NI=16:MI=NI-1
80 DX=F2-FX:DY=DX*(RY/RX)*2:IF SM=3 THEN DY=DY/2
480 E=FY
490 Y=0
495 WHILE Y<RY
500   D=FX
510   X=0:REM FOR X=0 TO MX
515   WHILE X<RX
516 LOCATE 1,1:PRINT (Z2+I2)
520     Z=0:I=0:A=0:z2=0:i2=0
525     WHILE ((A<MI)) AND ((Z2+I2)<4)
530       S=(Z2)-(I2)+D:R=(2*I*Z)+E:Z=S:I=R:A=A+1:z2=z*z:i2=i*i
540     WEND
550     IF SM=4 THEN C=0 ELSE C=3
570       IF SM=3 THEN GOSUB 2000:REM 4 COLOR PALETTE
590   '    IF (A AND 1)=0 THEN GOSUB 1190 ELSE GOSUB 1210
770     D=D+DX/RX:REM D=D+0.013437
780     X=X+1
785     WEND
790   E=E+DY/RY:REM E=E+0.013541
800   Y=Y+1
805   WEND
810 END
1190 REM -- WHITE STRIP --
1200 C=1:RETURN
1210 REM -- WHITE-BLACK PATTERN --
1220 IF (X AND 1)=(Y AND 1) THEN C=1
1230 RETURN
1300 REM -- GREEN-YELLOW PATTERN --
1310 IF (X AND 1)=(Y AND 1) THEN C=3 ELSE C=1
1320 RETURN
1330 REM -- YELLOW --
1340 C=1:RETURN
1350 REM -- YELLOW-RED PATTERN --
1360 IF (X AND 1)=(Y AND 1) THEN C=1 ELSE C=2
1370 RETURN
1380 REM -- RED --
1390 C=2:RETURN
1400 REM -- RED-BLUE PATTERN --
1410 IF (X AND 1)=(Y AND 1) THEN C=2 ELSE C=0
1420 RETURN
1430 REM -- BLUE --
1440 C=0:RETURN
1450 REM -- BLUE-GREEN PATTERN --
1460 IF (X AND 1)=(Y AND 1) THEN C=0 ELSE C=3
1470 RETURN
2000 K=(A/8)-INT(A/8)
2010 J=K*8
2020 ON J GOSUB 1300,1330,1350,1380,1400,1430,1450
2025 PLOT X*2,Y*2,C
2030 RETURN



I had a few goes trying to get this to run in Hisoft Pascal, as I posted earlier the trouble with the arithmetic AND. I've overcome that problem by setting up two Boolean types (rst1 & rst2), and as I mentioned in my previous post I've used odd to determine if "xpos" or "ypos" are odd numbers. Once I've tested those I can test if rst1 & rst2 are the same to alternate the colours. My first result was close to the original BASIC but lacked the Dark Blue in the Mandelbrot as this screenshot shows:


[attach=2]


In the BASIC it has another IF, so IF SM=4 THEN C=0 ELSE C=3, in my Pascal program SM always equals 3, which I defined as a CONSTant, so have just put col:=3; in the appropriate spot which gets me the right result:


[attach=3]


So here's the Pascal code I came up with:




   10 PROGRAM Mandelbrot;
   20
   30 CONST ft=1; sm=3; pa=0; mi=15; ni=16;
   40       fx=-2.4; f2=1.04; fy=-1.3;
   50       rx=320; ry=200;
   60
   70 PROCEDURE mode(num : integer);
   80 BEGIN
   90   ra:=chr(num);
  100   user(#bc0e)
  110 END;
  120
  130 PROCEDURE ink(num,col1 : integer);
  140 BEGIN
  150   ra:=chr(num);
  160   rb:=chr(col1);
  170   rc:=chr(col1);
  180   user(#bc32)
  190 END;
  200
  210 PROCEDURE border(col : integer);
  220 BEGIN
  230   rb:=chr(col);
  240   rc:=chr(col);
  250   user(#bc38)
  260 END;
  270
  280 PROCEDURE plot(xpos,ypos,col : integer);
  290 BEGIN
  300   ra:=chr(col);
  310   user(#bbde);
  320   rde:=xpos;
  330   rhl:=ypos;
  340   user(#bbea)
  350 END;
  360
  370 PROCEDURE drawbolt;
  380 VAR xpos : integer;
  390     ypos : integer;
  400     col  : integer;
  410     dx   : real;
  420     dy   : real;
  430     d    : real;
  440     a    : integer;
  450     s    : real;
  460     z2   : real;
  470     z    : real;
  480     i2   : real;
  490     i    : real;
  500     e    : real;
  510     k    : real;
  520     j    : integer;
  530     r    : real;
  540     rst1 : boolean;
  550     rst2 : boolean;
  560 BEGIN
  570   dx:=0.0; dy:=0.0;
  580   dx:=f2-fx;
  590   dy:=dx*(ry/rx)*2;
  600   dy:=dy/2;
  610   e:=fy;
  620   ypos:=0;
  630   WHILE ypos<ry DO
  640   BEGIN
  650     d:=fx;
  660     xpos:=0;
  670     WHILE xpos<rx DO
  680     BEGIN
  690       z:=0.0; i:=0.0; a:=0; z2:=0.0; i2:=0.0;
  700       WHILE ((a<mi)) AND ((z2+i2)<4.0) DO
  710       BEGIN
  720         s:=(z2)-(i2)+d;
  730         r:=(2*i*z)+e;
  740         z:=s;
  750         i:=r;
  760         a:=a+1;
  770         z2:=z*z;
  780         i2:=i*i
  790       END;
  800       col:=3;
  810       rst1:=odd(xpos);
  820       rst2:=odd(ypos);
  830       k:=(a/8)-trunc(a/8);
  840       j:=entier(k*8);
  850       CASE j OF
  860        1   : IF (rst1=rst2) THEN col:=1 ELSE col:=3;
  870        2   : col:=1;
  880        3   : IF (rst1=rst2) THEN col:=2 ELSE col:=1;
  890        4   : col:=2;
  900        5   : IF (rst1=rst2) THEN col:=0 ELSE col:=2;
  910        6   : col:=0;
  920        7   : IF (rst1=rst2) THEN col:=3 ELSE col:=0
  930       END;
  940       plot(xpos*2,ypos*2,col);
  950       IF col=1 THEN col:=1 ELSE col:=1;
  960       d:=d+dx/rx;
  970       xpos:=xpos+1
  980       END;
  990     e:=e+dy/ry;
1000     ypos:=ypos+1
1010   END;
1020 END;
1030 BEGIN
1040 mode(1); border(6); ink(0,6); ink(1,18); ink(2,26); ink(3,1);
1050 drawbolt
1060 END.






Title: Re: Mandelbrot with Amstrad
Post by: litwr on 16:19, 07 November 16
Quote from: AMSDOS on 02:08, 05 November 16
I wouldn't go as far as to say it's impossible, but the problem I'm having here is writing it structurally, it's structurally complicated. Unfortunately this is not the 1st BASIC program I've stumbled over, I have tried to structurally write a Snow Flake Graphical program, unfortunately without any success.

The obvious solution is to throw away the structured principals and surrender to the GOTO command! In BASIC a GOTO can go anywhere, but in Pascal it cannot, labels have to be declared at the beginning of a PROCEDURE and GOTO is restricted to within a PROCEDURE.
So we need to rewrite Basic sources at first.  It is impossible to work with unbalanced NEXT with the popular modern PL.
It is interesting, how much faster Pascal code is?
Color Mandelbrot is ok but higher resolution mono picture is ok too.  ;) BTW the mentioned program BBC Micro builds color Mandelbrot (184x272, 8 colors) with infinite zoom in feature.
Title: Re: Mandelbrot with Amstrad
Post by: AMSDOS on 21:19, 07 November 16
Quote from: litwr on 16:19, 07 November 16
So we need to rewrite Basic sources at first.  It is impossible to work with unbalanced NEXT with the popular modern PL.
It is interesting, how much faster Pascal code is?
Color Mandelbrot is ok but higher resolution mono picture is ok too.  ;) BTW the mentioned program BBC Micro builds color Mandelbrot (184x272, 8 colors) with infinite zoom in feature.

Sorry I'm not quite following your comments at the moment.

There's a binary file on the attached DSk image you can run to see how fast it runs. Sorry I didn't include the BASIC version with it. It could possibly be made faster if some compiler operatives are used even. If you take the BASIC version, paste it into winape enable turbo mode and increase speed to 150% that will produce something close to the pascal version.


EDIT:I've done some rough stopwatch timings between the BASIC and Pascal programs I posted earlier, which roughly shows the BASIC took 3 hours 22 Minutes & 42 Seconds to complete. The translation to Pascal meant it was complete in 27 Minutes & 51 Seconds. But I suspect a BASIC compiler could even things up.


I don't think I'll ever get it down to 2 Minutes unless it's a screen dump, even my precompiled colour data one that is used by my earlier Turbo Pascal version isn't even that fast.
Title: Re: Mandelbrot with Amstrad
Post by: AMSDOS on 09:20, 08 November 16
Quote from: SRS on 21:20, 05 October 16
Well done :)

But: why monocolored in MODE 1 ?

I don't get why the very big (and slow) arrays are needed ? Maybe to late for me [attach=2] today ;)

Using 16 iterations per pixel, some y-symmetrics, four colors and saving 30 "empty" pixels left and right
a color mandel in 32 minutes.


I like this one and it's approach, but it took something like 1h24mins to complete, but that was in BASIC 1.0, unfortunately I didn't see the process complete itself, so I don't know if TIME was passing was being added, while the keypress routine was holding it there, though I checked it around the 40 minute mark and it was still drawing. Unsure. BASIC 1.1 would have improved the timing of it, though 32 minutes sounds awfully impressive improvement.


I'm just wondering on the back of the Mandelbrot is that Gap, in your code the plot that's plotting from the top for the ypos starts at 400 with a variable (which I don't remember what it's called) starts at 0. 398 is the very top line (400 is offscreen), just wondered if that was the fault causing that gap to occur? Unfortunately I didn't have time to test this.  :o
Title: Re: Mandelbrot with Amstrad
Post by: litwr on 21:36, 08 November 16
Quote from: AMSDOS on 21:19, 07 November 16
Sorry I'm not quite following your comments at the moment.
Sorry for possible grammar quirks. :( Is it about unbalanced NEXT or a program for BBC Micro?  I also wrote that monochrome high resolution Mandelbrot may look quite fine.
I can't imagine what makes Pascal code about 7 times faster...
Title: Re: Mandelbrot with Amstrad
Post by: AMSDOS on 10:40, 09 November 16
Quote from: litwr on 21:36, 08 November 16
Sorry for possible grammar quirks. :( Is it about unbalanced NEXT or a program for BBC Micro?  I also wrote that monochrome high resolution Mandelbrot may look quite fine.
I can't imagine what makes Pascal code about 7 times faster...


Apologies, I hijacked your thread. I was initially responding to @robcfg (http://www.cpcwiki.eu/forum/index.php?action=profile;u=4) Mandelbrot which I worked out by pulling it apart and remove all the GOTO lines which wouldn't be required for the Pascal. I ended up with that BASIC program which took nearly 3.5 hrs to complete in BASIC and around 28Minutes in Pascal. The timing of the Mandelbrot can vary depending on the Iterations, I only had 16 in my Pascal, but the more I added I started noticing everything slowing down, though Pascal is always Compiled into Machine Code, that improves performance (as you're probably aware?). The initial Mandelbrot @robcfg (http://www.cpcwiki.eu/forum/index.php?action=profile;u=4) posted has a Blue centre, but when I stripped it down to the BASIC version, it's rendering the centre, which my Pascal version is also doing. I thought it might of been due to the number of Interations I had, but that doesn't seem to be the case, so I'm unsure why that's happening.  ???


I was then looking at SRS which simply fills around the edges which saves time in using the background for the centre of the mandelbrot, but should have been looking at your mandelbrot. For some reason I thought it was in Mode 2, but I should have been looking at the code rather than the screenshot. Like the one SRS posted it shouldn't be too difficult to interpret into Pascal. Just gone on what SRS said, an Array I don't think is necessary, I see your's has 3, must be taking up large amounts of Data, that maybe more of a problem in a Compiled Language like Pascal, BASIC probably has the edge there since it's a small program located at &170. Unfortunately I don't have the means of playing around with your program at the moment, I was just wondering if you needed to subtract t% twice in your PLOT & TEST commands, instead of using STEP 2 in your FOR t%=0 TO 199 STEP 2, which is faster I think. Also I noticed your starting your Mandelbrot off the top of the screen at 402, couldn't that be the top line at 398?

Title: Re: Mandelbrot with Amstrad
Post by: robcfg on 13:37, 09 November 16
It may sound silly, but you changed ON J GOSUB 1300,1330,1350,1380,1400,1430,1450 for CASE j OF 1..7, and I think the range of the case statement should be 0..6, so when the value of j is 7 it uses the chosen color which is 3.


I tried your program on Winape and it's amazingly fast in comparison to the BASIC one!


Please try to change the range and tell me if that works.
Title: Re: Mandelbrot with Amstrad
Post by: SRS on 21:42, 09 November 16
Quote from: AMSDOS on 09:20, 08 November 16
...though 32 minutes sounds awfully impressive improvement.

I'm just wondering on the back of the Mandelbrot is that Gap, in your code the plot that's plotting from the top for the ypos starts at 400 with a variable (which I don't remember what it's called) starts at 0. 398 is the very top line (400 is offscreen), just wondered if that was the fault causing that gap to occur? Unfortunately I didn't have time to test this.  :o

Well, 32 minutes was with "turbo mode" active (like DI .. EI). And that Gap ... as you said change 400 to 398 and its gone. I sometimes publish beta versions :)

You, Sir, should think about a career as software testmanager (if you aren't now) !

Title: Re: Mandelbrot with Amstrad
Post by: litwr on 06:19, 10 November 16
Quote from: AMSDOS on 10:40, 09 November 16

Apologies, I hijacked your thread. I was initially responding to @robcfg (http://www.cpcwiki.eu/forum/index.php?action=profile;u=4)
It is fine we have a fine thread. :)

Quote from: AMSDOS on 10:40, 09 November 16Unfortunately I don't have the means of playing around with your program at the moment, I was just wondering if you needed to subtract t% twice in your PLOT & TEST commands, instead of using STEP 2 in your FOR t%=0 TO 199 STEP 2, which is faster I think.
Thanks but it is not so easy.  STEP 2 will not work.
I've just made a Mandelbrot video for the BBC Micro program.  The program had worked during about 5 minutes but the video is accelerated.  The speed and the GUI are very good. :)  IMHO it is the best Mandelbrot in the 8-bit world.
[attachimg=1]
Title: Re: Mandelbrot with Amstrad
Post by: AMSDOS on 09:38, 10 November 16


Quote from: robcfg on 13:37, 09 November 16
It may sound silly, but you changed ON J GOSUB 1300,1330,1350,1380,1400,1430,1450 for CASE j OF 1..7, and I think the range of the case statement should be 0..6, so when the value of j is 7 it uses the chosen color which is 3.


I tried your program on Winape and it's amazingly fast in comparison to the BASIC one!


Please try to change the range and tell me if that works.


For some reason (probably due to the example in the Manual), I always think the 1st number the Subroutine goes to, is based on the variable having a value of 1, but in the Manual is suggests values can be between 0 and 255.


For the CASE statement I tried all sorts of combinations, 0 doesn't seem to be valid in this case because the lowest k can be is 0.25, which is then multiplied by 8 to return 1 for j, but eventually I've added an 8th routine to obtain the Blue for the Centre, I also had to change the values from the Iterations so mi=16 and ni=17, which gets me that Blue Centre.


Quote from: SRS on 21:42, 09 November 16
Well, 32 minutes was with "turbo mode" active (like DI .. EI). And that Gap ... as you said change 400 to 398 and its gone. I sometimes publish beta versions


I was gonna ask if you used turbo mode.  :D  I could whip it up in Pascal and it will probably be completed within 10 minutes.


QuoteYou, Sir, should think about a career as software testmanager (if you aren't now) !


Haven't always been able to debug an Amstrad program, C is probably avenue into that sort of career, sadly i need brushing up on.  :laugh:

Quote from: litwr on 06:19, 10 November 16
It is fine we have a fine thread. :)
Thanks but it is not so easy.  STEP 2 will not work.
I've just made a Mandelbrot video for the BBC Micro program.  The program had worked during about 5 minutes but the video is accelerated.  The speed and the GUI are very good. :)  IMHO it is the best Mandelbrot in the 8-bit world.



Huh! Sorry I still need to get to your code  :(  Okay I can see why STEP 2 wouldn't work, I was trying to use another approach instead of using Arrays.
Unfortunately I haven't looked at your program and so I'm baffled on lines 12 & 13. I can tell they are putting information into the r & j arrays, but that's about it.


Otherwise it's an interesting collection of Mandelbrot's, I'm somewhat surprised there's not that many on CPC-Power (well I only found 3).


And yeah I saw the BBC program (for some reason the GIF wouldn't work on Safari), that will take some doing.
Title: Re: Mandelbrot with Amstrad
Post by: robcfg on 09:46, 10 November 16
The BBC program is quite interesting, is there any source to take a look at?
Title: Re: Mandelbrot with Amstrad
Post by: litwr on 19:39, 10 November 16
Quote from: robcfg on 09:46, 10 November 16
The BBC program is quite interesting, is there any source to take a look at?
http://www.stardot.org.uk/forums/viewtopic.php?f=2&t=12028#p152674 (http://www.stardot.org.uk/forums/viewtopic.php?f=2&t=12028#p152674)
Title: Re: Mandelbrot with Amstrad
Post by: AMSDOS on 10:47, 11 November 16
Sorry I forgot to attach the updated Pascal program for anyone interested:


[attachimg=1]



Title: Re: Mandelbrot with Amstrad
Post by: RichTW on 12:58, 23 November 16
Quote from: litwr on 19:39, 10 November 16
http://www.stardot.org.uk/forums/viewtopic.php?f=2&t=12028#p152674 (http://www.stardot.org.uk/forums/viewtopic.php?f=2&t=12028#p152674)


Haha, how funny to find this discussion here!  I've just joined up to the forum, and I'm the author of this BBC Micro demo.  If anyone has any questions, I'm more than happy to (try to) answer them!  Basically it does colour boundary tracing in order to try to minimise the number of pixels it has to evaluate (which particularly helps when there are plenty of onscreen pixels "in" the Mandelbrot set, which take the greatest number of iterations).  It uses the low resolution mode (like MODE 0) with pairs of pixels, so they are square and can be dithered, in order to increase the apparent number of colours as the BBC only has an 8 colour palette.


The key to the speed is the boundary tracing, and the fast multiplication routine which uses the "difference of two squares" method with an additional optimization.  The source is there if you can read 6502!  I'm sure a CPC version would perform even better with a similar optimized Z80 multiply, and would look prettier too!
Title: Re: Mandelbrot with Amstrad
Post by: litwr on 19:59, 09 December 16
Quote from: RichTW on 12:58, 23 November 16
The key to the speed is the boundary tracing, and the fast multiplication routine which uses the "difference of two squares" method with an additional optimization.  The source is there if you can read 6502!  I'm sure a CPC version would perform even better with a similar optimized Z80 multiply, and would look prettier too!
IMHO BBC Micro is about 2 times faster for such kind of graphics but Amstrad CPC may show more colors.  BTW I thought that BBC Micro was a big rarity outside England.

Quote from: AMSDOS on 10:47, 11 November 16
Sorry I forgot to attach the updated Pascal program for anyone interested:
Thanks! :) I have checked it and even converted it back to Basic with slight optimization.  ;)

5 TI=TIME
10 MI%=15:FX=-2.4:F2=1.04:FY=-1.3:RX%=320:RY%=200
20 MODE 1:BORDER 6:INK 0,6:INK 1,18:INK 2,26:INK 3,1:GOSUB 580
25 PRINT (TIME-TI)/300
30 END
580 DX=F2-FX
590 DY=RY%/RX%*DX
610 E=FY
620 YP%=0
630 WHILE YP%<RY%
650 D=FX
660 XP%=0
670 WHILE XP%<RX%
690 S=0:R=0:A%=0:Z2=0:I2=0
700 WHILE(A%<MI%)AND(Z2+I2<4)
710 R=2*R*S+E
720 S=Z2-I2+D
760 A%=A%+1
770 Z2=S*S
780 I2=R*R
790 WEND
810 RST%=(XP%AND 1)=(YP%AND 1)
830 J%=A%AND 7
840 COL%=1
860 IF J%=1 THEN IF NOT RST% THEN COL%=3:GOTO 940 ELSE GOTO 940
870 IF J%=2 GOTO 940
880 IF J%=3 THEN IF RST% THEN COL%=2:GOTO 940 ELSE GOTO 940
890 COL%=2:IF J%=4 THEN 940
900 IF J%=5 THEN IF RST% THEN COL%=0:GOTO 940 ELSE GOTO 940
910 COL%=0:IF J%=6 GOTO 940
920 IF J%=7 THEN IF NOT RST% THEN 940
930 COL%=3
940 PLOT XP%*2,YP%*2,COL%
960 D=D+DX/RX%
970 XP%=XP%+1
980 WEND
990 E=E+DY/RY%
1000 YP%=YP%+1
1010 WEND
1020 RETURN

Hisoft Pascal shows very good quality of the generated code.  Its big disadvantage is impossibility to work with ASCII.  Is there any converter from ASCII?  I worked with MANBOLT.PAS.  The results:
Hisoft Pascal - 1807 sec (I've added GETTIMER procedure to the code)
Basic - 9754 sec
Basic with the code compressed by BPC - 9585 sec
Basic compiled by Fabacom - 3911 sec
I'd tried CPC Basic cross-compiler but it doesn't support the real numbers. :(
Fabacom has the manual in German and it is a scanned text.  So I can't use any translator. :(
Hisoft Pascal makes more than two times faster code.  I can think that this Basic compiler makes not pure machine code but uses p-codes.
Title: Re: Mandelbrot with Amstrad
Post by: AMSDOS on 22:12, 09 December 16
@litwr (http://www.cpcwiki.eu/forum/index.php?action=profile;u=1057) Like BASIC, Hisoft Pascal tokenises keywords to help reduce the amount of memory being used, which becomes more apparent when programs become larger. However I use it in Winape, so in the Printer Settings I can create a file (with the name of the program) & use the "Z" option in Hisoft Pascal which would dump the program to printer, but in this case it dumps it to a file (as ASCII). On occasions I've done this and have edited the programs with Notepad and used Winape to Paste the code, which Hisoft Pascal happily accepts (just be careful not to exceed 80 chars per line).


In CPC BASIC 3 Real Numbers are not usually supported, though a number of RSXs are available, in the guide I have it specifies that you have to state how many real numbers in a box at the top of the application window. The default is 0, which disables the RSXs available, any other number and the RSXs are available and a little bit of memory is assigned to a table, I haven't used this, but I think the larger the number the more table space is assigned, and is probably a good opportunity to test on a Mandelbrot.


The RSX commands available look like this:




|ABS,i1,i2: equivalent to the operation table(i1)=ABS(table(i2)).
|ADD,i1,i2,i3: equivalent to the operation table(i1)=table(i2)+table(i3).
|ATN,i1,i2: equivalent to the operation table(i1)=ATN(table(i2)).
|CINT,@variable,i: corresponds to the operation variable=CINT(table(i)), storing the index value i in the specified variable, ignoring the sign. Useful to pass the value of an item in the table of real values to a CPC Basic program variable.
|CMP,@variable,i1,i2: stored in variable a value 1 if table(i1)>table(i2), a value 0 if table(i1)=table(i2), or a value 255, interpetable as -1 if table(i1)<table(i2).
|COS,i1,i2: equivalent to the operation table(i1)=COS(table(i2)).
|CREAL,i,expression is equivalent to the operating table(i)=expression. Useful to pass a value of CPC Basic program to an item in the table of real values.
|DEG: equivalent to the command DEG.
|DIV,i1,i2,i3: equivalent to the operation table(i1)=table(i2)/table(i3).
|EXP,i1,i2: equivalent to the operation table(i1)=EXP(table(i2)).
|FIX,i1,i2: equivalent to the operation table(i1)=FIX(table(i2)).
|INT,i1,i2: equivalent to the operation table(i1)=INT(table(i2)).
|LET,i1,i2: equivalent to the operation table(i1)=table(i2).
|LOG,i1,i2: equivalent to the operation table (i1)=LOG(table(i2)).
|LOG10,i1,i2: equivalent to the operation table(i1)=LOG10(table(i2)).
|MUL,i1,i2,i3: equivalent to the operation table(i1)=table(i2)*table(i3).
|PI,i: corresponds to the operation table(i)=PI.
|POW,i1,i2,i3: equivalent to the operation table(i1)=table(i2)^table(i3).
|RAD: equivalent to the command RAD.
|REV,i1,i2: equivalent to the operation table(i1)=-table(i2).
|ROUND,i1,i2,expression: equivalent to the operation table(i1)=ROUND(table(i2),expression).
|SGN,@variable,i: corresponds to the variable operation=SGN(table(i)).
|SIN,i1,i2: equivalent to the operation table(i1)=SIN(table(i2)).
|SQR,i1,i2: equivalent to the operation table(i1)=SQR(table(i2)).
|STR,@variable,i: corresponds to the operation variable=STR$(table(i)), where variable is of type string and with a minimum length of 11 characters.
|SUB,i1,i2,i3: equivalent to the operation table(i1)=table(i2)-table(i3).
|TAN,i1,i2: equivalent to the operation table(i1)=TAN(table(i2)).
|VAL,i,@variable: equal to the operating table(i)=VAL(variable) where variable is of type string or can also be a string constant without the @ operator.





If you do manage to get it to work, the result will probably be an improvement on Hisoft Pascal.
Title: Re: Mandelbrot with Amstrad
Post by: RichTW on 22:48, 09 December 16
Quote from: litwr on 19:59, 09 December 16
IMHO BBC Micro is about 2 times faster for such kind of graphics but Amstrad CPC may show more colors.  BTW I thought that BBC Micro was a big rarity outside England.
In the Mandelbrot program, the slow part is iterating the z2+c until it diverges or reaches the iteration limit - using the difference of squares method to perform the multiplies, it can be reduced to a bunch of 16 bit subtractions, followed by a bunch of 16 bit additions, and this is something that the Z80 has the edge over the 6502 (16 bit arithmetic in general).  But given the effective clock speed (2MHz 6502 versus ~3.3MHz Z80), maybe it ends up roughly the same.


The actual plotting is not really a bottleneck.  But the CPC could certainly render it much better, given its far nicer palette!


Yeah the BBC Micro was pretty much only seen in the UK - I spent my childhood years there before moving to Spain.
Title: Re: Mandelbrot with Amstrad
Post by: robcfg on 23:39, 09 December 16
@litwr (http://www.cpcwiki.eu/forum/index.php?action=profile;u=1057) , is there a source or explanation of the techniques used in the BBC program?


I find that much 6502 assembler a little too much too digest.
Title: Re: Mandelbrot with Amstrad
Post by: RichTW on 09:23, 10 December 16
I wrote a little about the multiplication technique that it uses here (http://www.stardot.org.uk/forums/viewtopic.php?p=154856#p154856) - that's pretty much the guts of the program. The values it manipulates are fixed-point, holding 29 fractional bits and 3 signed integer bits, allowing values between -4.0 and <4.0. A cute consequence of the method is that it can square a number slightly more quickly than multiply two different numbers, which is great as there are two square operations per iteration!


The border tracing is fairly straightforward, but instead of using recursion it maintains a queue of pixels to process, and carries on until there's nothing left in the queue. First thing it does is pushes all the screen edge pixels to the queue. Then the algorithm is:


For each item in the queue:
Once the queue is empty, we have all the borders rendered on screen (the border is actually two-sided, containing both colours). Now we just do a full screen pass to fill in the colour. This is simple, for any pixel not yet drawn, we just duplicate the pixel directly above, and iterate in columns, top to bottom, left to right.


This approach requires two special pixel values - one to denote that the pixel hasn't been written, and one to denote that a pixel has already been added to the queue (otherwise we could quickly fill the queue with duplicates). On the Beeb version, I use a bit each for these two things. This is possible because the Beeb has 4bpp but only 8 unique colours - I pair up pixels vertically so I can dither, and use the top bits of each to indicate these two different things. This is just an implementation detail though. On the CPC there's enough memory to be able to store these bit arrays separately from the screen.


Hope that clarifies things a bit. Who's going to be the first to make a CPC version then?  :)
Title: Re: Mandelbrot with Amstrad
Post by: litwr on 17:15, 11 December 16
Quote from: AMSDOS on 22:12, 09 December 16
@litwr (http://www.cpcwiki.eu/forum/index.php?action=profile;u=1057) Like BASIC, Hisoft Pascal tokenises keywords to help reduce the amount of memory being used, which becomes more apparent when programs become larger. However I use it in Winape, so in the Printer Settings I can create a file (with the name of the program) & use the "Z" option in Hisoft Pascal which would dump the program to printer, but in this case it dumps it to a file (as ASCII). On occasions I've done this and have edited the programs with Notepad and used Winape to Paste the code, which Hisoft Pascal happily accepts (just be careful not to exceed 80 chars per line).
Basic may save/load ASCII.  The paste function is very useful.  Ep128emu missed it.  So I used the internal Hisoft Pascal editor.  It is not easy to work with it...  Did anybody try to use graphics with Turbo Pascal?  Turbo Pascal works with ASCII and has the very friendly editor...  I wrote a lot of Turbo Pascal codes for Amstrad CPC/PCW at the 80s but I never used graphics. :(

Quote from: AMSDOS on 22:12, 09 December 16
In CPC BASIC 3 Real Numbers are not usually supported, though a number of RSXs are available, in the guide I have it specifies that you have to state how many real numbers in a box at the top of the application window. The default is 0, which disables the RSXs available, any other number and the RSXs are available and a little bit of memory is assigned to a table, I haven't used this, but I think the larger the number the more table space is assigned, and is probably a good opportunity to test on a Mandelbrot.
If you do manage to get it to work, the result will probably be an improvement on Hisoft Pascal.
I'm not sure because we should replace all arithmetic by these ugly and slow RSX...


Quote from: RichTW on 22:48, 09 December 16
In the Mandelbrot program, the slow part is iterating the z2+c until it diverges or reaches the iteration limit - using the difference of squares method to perform the multiplies, it can be reduced to a bunch of 16 bit subtractions, followed by a bunch of 16 bit additions, and this is something that the Z80 has the edge over the 6502 (16 bit arithmetic in general).  But given the effective clock speed (2MHz 6502 versus ~3.3MHz Z80), maybe it ends up roughly the same.
The actual plotting is not really a bottleneck.  But the CPC could certainly render it much better, given its far nicer palette!
z80 @3.2 MHz is generally as fast as 6502 @1.33 MHz. A skilled z80 programmer may do codes as fast as 6502 @1.5 MHz but it is very uneasy.  Z80 requires more hard work to get the faster code than 6502. z80 is good with division but for fast table multiplication 6502 is better...
Amstrad CPC's Video memory layout is more complex to use than BBC Micro's.  So I gave my estimates about 2 times speed difference.  16 colors will require more time too.


Quote from: robcfg on 23:39, 09 December 16
I find that much 6502 assembler a little too much too digest.
Agreed, it is very difficult to convert 6502 codes to z80.  The backward conversion is much easier.  However for a man with experience with 6809 6502 should not be too alien.
Title: Re: Mandelbrot with Amstrad
Post by: AMSDOS on 09:37, 12 December 16
Quote from: litwr on 17:15, 11 December 16
Basic may save/load ASCII.  The paste function is very useful.  Ep128emu missed it.  So I used the internal Hisoft Pascal editor.  It is not easy to work with it...  Did anybody try to use graphics with Turbo Pascal?  Turbo Pascal works with ASCII and has the very friendly editor...  I wrote a lot of Turbo Pascal codes for Amstrad CPC/PCW at the 80s but I never used graphics. :(


In that case I'd suggest Hisoft Pascal 80. It operates in CP/M like Turbo Pascal (and compiles programs for CP/M like TP), supports ASCII files, I don't remember what you use to edit the programs, but at least the manual for HP80 documents how to incorporate GSX into your programs. It's possible to do in Turbo Pascal I think, but it's not documented in the manual (version 3), and you really need to find someone who knows how to do it.

Quote from: litwr
I'm not sure because we should replace all arithmetic by these ugly and slow RSX...



I've only encountered "slow RSX" from within Interpreted Locomotive BASIC which had to spend more time translating the ASCII component from within the bar command & people were suggesting a tokenised CALL had better response time. From a compiled language, this doesn't seem to be an issue, though from CPC BASIC 3, you can produce an output file in Assembly, which should reveal those RSX routines, it would just be a matter of finding the appropriate routines.
Title: Re: Mandelbrot with Amstrad
Post by: litwr on 11:20, 12 December 16
Quote from: AMSDOS on 09:37, 12 December 16
I've only encountered "slow RSX" from within Interpreted Locomotive BASIC which had to spend more time translating the ASCII component from within the bar command & people were suggesting a tokenised CALL had better response time. From a compiled language, this doesn't seem to be an issue, though from CPC BASIC 3, you can produce an output file in Assembly, which should reveal those RSX routines, it would just be a matter of finding the appropriate routines.
Try to imagine the complete ugliness of R=2*R*S+E expression in the RSX syntax...
Title: Re: Mandelbrot with Amstrad
Post by: litwr on 21:43, 12 December 16
I have run AMSDOS's program with Turbo Pascal under CP/M 2.2.  It takes 4804 seconds.  So its codes are not so good as Hisoft Pascal.  However Turbo Pascal has better editor, disk i/o support, a lot of libraries, ...
Nobody has mentioned the very fast programs for Amstrad CPC - http://www.octoate.de/wp/?s=mavdelbrot (http://www.octoate.de/wp/?s=mavdelbrot)...
IMHO the bw picture at the beginning of this thread shows pixels in the most accurate way.
Title: Re: Mandelbrot with Amstrad
Post by: AMSDOS on 23:42, 12 December 16
Quote from: litwr on 11:20, 12 December 16
Try to imagine the complete ugliness of R=2*R*S+E expression in the RSX syntax...

Hmm I see your point, I'm not quite sure what you would use in CPC BASIC 3 for that either.



Quote from: litwr on 21:43, 12 December 16
I have run AMSDOS's program with Turbo Pascal under CP/M 2.2.  It takes 4804 seconds.  So its codes are not so good as Hisoft Pascal.  However Turbo Pascal has better editor, disk i/o support, a lot of libraries, ...


I think I know which Mandelbrot program you're referring to, it's the one posted on the forum.
I don't know why it takes longer, it was originally written in Modula-2 before someone converted it to turbo pascal 6 before I converted it to turbo pascal 3, but that was all done on the IBM-PC version.
I'm unsure what video mode I was using 640x480x16 I think, so it took a bit of effort just to have that one working on a CPC.
I'm unsure if there's anything within it which is just wasting time, it appears to be stripped down to do what it needs to do, the next thing I looked at was what the Turbo Pascal version has. The Hisoft Pascal version doesn't use the SQR() function, Turbo Pascal maybe slow in that regard to SQR().
The Turbo Pascal program is using a FUNCTION to obtain a colour value, and from within that FUNCTION a loop is declared which I think would be holding things up. The Hisoft Pascal version has loops within it's main loop (no function has been declared), so the result for the colour is obtained faster and CASE is used to determine the Colour based on the True/False results from rst1 & rst2.
So there's a good chance that what I converted to CPC earlier lags since it's code is derived from a faster computer, there maybe some other things in it which might be slowing the program down, as you pointed out it works in CP/M 2.2 and I was using Turbo Pascal to incorporate Firmware Instructions. To do that from CP/M 2.2 you need to use the assigned Enter Firmware Call to access Firmware and as the program requires obtaining Colours & Plotting Pixels heavily, however much slower that is compared to having direct access (which Hisoft Pascal has), could explain the time difference.
Title: Re: Mandelbrot with Amstrad
Post by: litwr on 16:28, 13 December 16
I had used your Hisoft Pascal sources with Turbo Pascal.  I has only slightly adjusted them.  ;)

PROGRAM Mandelbrot;

{$i firmware.lib}

CONST ft=1; sm=3; pa=0; mi=15; ni=16;
      fx=-2.4; f2=1.04; fy=-1.3;
      rx=320; ry=200;

VAR timer:real;

function get_timer: real;
   var
      hl, de: integer;
begin
       Inline($CD/$9B/$BE/
          $0D/$DB/
          $22/hl/
          $ed/$53/de);
       if hl<0 then
          get_timer := ((de+1)*65536.0+hl)/300
       else
          get_timer := (de*65536.0+hl)/300
end;

PROCEDURE drawbolt;
VAR xpos : integer;
    ypos : integer;
    col  : integer;
    dx   : real;
    dy   : real;
    d    : real;
    a    : integer;
    s    : real;
    z2   : real;
    z    : real;
    i2   : real;
    i    : real;
    e    : real;
    j    : integer;
    r    : real;
    rst : boolean;
BEGIN
  dx:=0.0; dy:=0.0;
  dx:=f2-fx;
  dy:=dx*(ry/rx)*2;
  dy:=dy/2;
  e:=fy;
  ypos:=0;
  WHILE ypos<ry DO
  BEGIN
    d:=fx;
    xpos:=0;
    WHILE xpos<rx DO
    BEGIN
      z:=0.0; i:=0.0; a:=0; z2:=0.0; i2:=0.0;
      WHILE ((a<mi)) AND ((z2+i2)<4.0) DO
      BEGIN
        s:=(z2)-(i2)+d;
        r:=(2*i*z)+e;
        z:=s;
        i:=r;
        a:=a+1;
        z2:=z*z;
        i2:=i*i
      END;
      col:=3;
      rst := odd(xpos) = odd(ypos);
      j:=a and 7;
      CASE j OF
       1   : IF (rst) THEN col:=1 ELSE col:=3;
       2   : col:=1;
       3   : IF (rst) THEN col:=2 ELSE col:=1;
       4   : col:=2;
       5   : IF (rst) THEN col:=0 ELSE col:=2;
       6   : col:=0;
       7   : IF (rst) THEN col:=3 ELSE col:=0
      END;
      grapen(col);
      plot(xpos*2,ypos*2);
      IF col=1 THEN col:=1 ELSE col:=1;
      d:=d+dx/rx;
      xpos:=xpos+1
      END;
    e:=e+dy/ry;
    ypos:=ypos+1
  END;
END;
BEGIN
  mode(1);
  border(6);
  ink(0,6);
  ink(1,18);
  ink(2,26);
  ink(3,1);
  timer := get_timer;
  drawbolt;
  writeln(get_timer-timer:8:2);
  repeat until keypressed;
  mode(2)
END.

The FIRMWARE module is taken from http://turpas3.angelfire.com/ (http://turpas3.angelfire.com/).  The results show that quality of Hisoft Pascal codes is much higher than Turbo Pascal codes.  I commented the calls to plot and grapen and got 4606 seconds.  So this code should be only slightly slower with CP/M+.  Hisoft Pascal codes prove that they are 2.5 times faster.  It is a very good compiler but without ASCII and proper disc i/o support and with a very poor editor.
Title: Re: Mandelbrot with Amstrad
Post by: AMSDOS on 11:05, 15 December 16
I'm not sure why Turbo Pascal would be taking so long to get the job done. At one stage I discovered Turbo Pascal was being slow for drawing a simple circle (as found in the Amstrad manual's), though those were using COS & SIN (I also had to use a formula to calculate in degrees), the explanation I got for TP being so slow in that was BASIC was using Lookup Tables to get it's results. Still either of those are used in this Mandelbrot and program is still functions poorly. I can only conclude that TP struggles when it's dealing in the Math, I demonstrated earlier that storing the results in an array works better in TP, as opposed to calculating the result.
Title: Re: Mandelbrot with Amstrad
Post by: AMSDOS on 13:18, 14 January 17
I've gone back to the 1st Mandelbrot example in this thread and have written a Hisoft Pascal example of one, but I haven't got the result quite right, apart from the occasion where I took this screenshot of it:


[attachimg=1]


followed by the code I made up for it:




   10 PROGRAM Mandelbrot;
   20
   30 CONST r0=-1.9; r1=0.5; j0=-0.1; j1=0.95; n=30;
   40
   50 VAR data : ARRAY[0..2,0..319] OF integer;
   60       j2 : ARRAY[0..199] OF real;
   70       dj : real;
   80       dr : real;
   90        t : integer;
  100        s : integer;
  110        m : integer;
  120        x : real;
  130        y : real;
  140       xy : real;
  150        r : real;
  160        j : real;
  170       x2 : real;
  180       y2 : real;
  190        i : integer;
  200        z : integer;
  210        a : integer;
  220        b : integer;
  230        c : integer;
  240
  250 PROCEDURE mode(num : integer);
  260 BEGIN
  270   ra:=chr(num);
  280   user(#bc0e)
  290 END;
  300
  310 PROCEDURE plot(x,y,col : integer);
  320 BEGIN
  330   ra:=chr(col);
  340   user(#bbde);
  350   rde:=x;
  360   rhl:=y;
  370   user(#bbea)
  380 END;
  390
  400 PROCEDURE ink(ink,col1 : integer);
  410 BEGIN
  420   ra:=chr(ink);
  430   rb:=chr(col1);
  440   rc:=chr(col1);
  450   user(#bc32)
  460 END;
  470
  480 FUNCTION rdkey : char;
  490 BEGIN
  500   user(#bb1b);
  510   rdkey:=ra
  520 END;
  530
  540 FUNCTION test(xpos,ypos : integer) : integer;
  550 BEGIN
  560   rde:=xpos;
  570   rhl:=ypos;
  580   user(#bbf0);
  590   test:=ord(ra)
  600 END;
  610
  620 BEGIN {Main PROGRAM}
  630   a:=0; b:=1; c:=2;
  640   dr:=(r1-r0)/320;
  650   dj:=(j1-j0)/200;
  660   FOR t:=0 TO 199 DO
  670     j2[199-t]:=j0+dj*t;
  680   mode(1); ink(0,1); ink(1,26);
  690   FOR t:=2 TO 199 DO
  700   BEGIN
  710     j:=j2[t];
  720     FOR s:=2 TO 319 DO
  730     BEGIN
  740       r:=r0+dr*s;
  750       x:=r;
  760       y:=j;
  770       i:=1;
  780       x2:=x*x;
  790       y2:=y*y;
  800       WHILE (x2+y2<4) AND (i<=n) DO
  810       BEGIN
  820         xy:=x*y;
  830         x:=x2-y2+r;
  840         y:=2*xy+j;
  850         i:=i+1;
  860         x2:=x*x;
  870         y2:=y*y
  880       END; {WHILE Interation Statement}
  890       data[c,s]:=i;
  900       IF (i<=n) THEN plot(s+s,400-(t*2),1);
  910       IF (s<319) OR (t<199) THEN
  920       BEGIN
  930         IF test(s+s-2,402-(t*2))<>0 THEN
  940         BEGIN
  950          m:=data[b,s-1];
  960          IF (data[b,s-2]<m) AND (data[b,s]<m) THEN plot(s+s-2,402-(t*2),0);
  970          IF (data[a,s-2]<m) AND (data[b,s]<m) THEN plot(s+s-2,402-(t*2),0);
  980          IF (data[c,s-2]<m) AND (data[a,s]<m) THEN plot(s+s-2,402-(t*2),0);
  990          IF (data[a,s-1]<m) AND (data[c,s-1]<m)THEN plot(s+s-2,402-(t*2),0)
1000         END {IF test Statement}
1010       END; {IF s OR t is Less than 2}
1020     END; { FOR S Statement }
1030     z:=a; a:=b; b:=c; c:=z;
1040   END { FOR T Statement }
1050 END. {Main PROGRAM}



I've also attached the DSK image.
Title: Re: Mandelbrot with Amstrad
Post by: SRS on 17:41, 14 January 17
Looking at the Mandelbrot Example running (slow!) from here  http://turpas3.angelfire.com/
with WinApe debugger it seems the code is using EXX and EX AF,AF' almost every time it works with a register .. so this may be one reason why it is slower than HiSoft.


Title: Re: Mandelbrot with Amstrad
Post by: AMSDOS on 01:42, 15 January 17
Quote from: SRS on 17:41, 14 January 17
Looking at the Mandelbrot Example running (slow!) from here  http://turpas3.angelfire.com/
with WinApe debugger it seems the code is using EXX and EX AF,AF' almost every time it works with a register .. so this may be one reason why it is slower than HiSoft.

I guess if you've got a lot of them combined, both of those instructions use up 8 clock cycles.

The other problem with Turbo Pascal is it has to run on a number of CP/M systems, it needs a Z80 system though. Hisoft initially developed their Pascal on a Spectrum and there was a number of versions from what I understand. The Amstrad version of it seems to just have a release date of 26/9/84 and comes with provisions to easily access the Amstrads firmware, along with a couple of other specific Amstrad related Procedures & Functions.

I'm glad I've moved from Turbo Pascal to Hisoft Pascal, though was initially ranting about Hisoft Pascal on c.s.a.8, mainly about the editor, though would not of had a manual either & using a different emulator at the time (probably Caprice). Richard was nice enough to add an Paste option in Winape which allows me to use a Text editor and simply Paste the code, which the Hisoft Pascal editor handles quite well, even though it goes against what one did when coding on an Real Amstrad.
Powered by SMFPacks Menu Editor Mod