mandelbrot drawing CPU benchmark

The Speccy's spritely young offspring. Discuss everything from FPGA to ZX
Post Reply
danboid
Dizzy
Posts: 62
Joined: Sun May 12, 2024 11:16 am

mandelbrot drawing CPU benchmark

Post by danboid »

Youtube channel The Retro Desk created a mandelbrot drawing program that they have used to benchmark the CPU performance of various (modern) retro computer platforms. You can download the code for this benchmark for various platforms here:

https://github.com/SlithyMatt/multi-mandlebrot

Z80N assembler code is present in that repo but I do not know (Z80) assembler so I have been unable to get it to build and they haven't uploaded any binaries for the Next. I'd like to know how the Z80N running at full speed (28 Mhz) compares to the Agon Light 2 and the Uzebox. I already know the Uzebox is the fastest but by how much, compared to the Next?

I have looked at some other bits of asm for the Next and it seems that if I want to build this with sjasmplus then I need to do at least two things, I think:

Add some statements like these to the top of the file:

Code: Select all

; Allow Next paging and instructions
	DEVICE ZXSPECTRUMNEXT
	SLDOPT COMMENT WPMEM, LOGPOINT, ASSERTION
Then the hard part is getting the SAVENEX statements right which it seems need to go at the end of the .asm file. I tried the following which didn't work because I copy/pasted it without really understanding wtf I am doing, as I freely admit:

Code: Select all

;;--------------------------------------------------------------------
;; Set up .nex output
;;--------------------------------------------------------------------

	; This sets the name of the project, the start address,
	; and the initial stack pointer.
	SAVENEX OPEN "mand24.nex", 0, $ff40

	; This asserts the minimum core version.  Set it to the core version
	; you are developing on.
	SAVENEX CORE 2, 0, 0

	; This sets the border colour while loading (in this case white),
	; what to do with the file handle of the nex file when starting (0 =
	; close file handle as we're not going to access the project.nex
	; file after starting.  See sjasmplus documentation), whether
	; we preserve the next registers (0 = no, we set to default), and
	; whether we require the full 2MB expansion (0 = no we don't).
	SAVENEX CFG 7, 0, 0, 0

	; Generate the Nex file automatically based on which pages you use.
	SAVENEX AUTO
This doesn't work. I get some nonsense error when I run it instead of a fractal being drawn. I've read the sjasmplus docs for SAVENEX and I was absolutely none the wiser and I am out of my depth here. It goes without saying you can't fix code you don't understand.

Could someone who does know z80 for the Next please take pity and tell me how I get these programs building and running? I can then submit a PR for the repo if you don't want to do that, although it looks like its a dead project.

Any recommended tutorials for assembly coding on the Next?
User avatar
flatduckrecords
Manic Miner
Posts: 831
Joined: Thu May 07, 2020 11:47 am
Location: Oban, Scotland
Contact:

Re: mandelbrot drawing CPU benchmark

Post by flatduckrecords »

It looks like the asm files in the ZXN directory already have the correct SjASMPlus directives, so I was able to assemble just by running the build.sh file, but you could also invoke it directly:

Code: Select all

sjasmplus --lst zxn-mandelbrot.asm
sjasmplus --lst zxn-mandelbrot2.asm
sjasmplus --lst zxn-mandelbrot_127_63_15.asm
sjasmplus --lst zxn-mandelbrot_max_lores.asm
sjasmplus --lst zxn-mandelbrot_max_layer2.asm
If that doesn't work I can share the assembled .nex files.
User avatar
Einar Saukas
Bugaboo
Posts: 3213
Joined: Wed Nov 15, 2017 2:48 pm

Re: mandelbrot drawing CPU benchmark

Post by Einar Saukas »

danboid wrote: Wed May 15, 2024 10:41 am Youtube channel The Retro Desk created a mandelbrot drawing program that they have used to benchmark the CPU performance of various (modern) retro computer platforms.
More like a benchmark of someone's programming skills in various retro computer platforms :)

For instance here:

https://github.com/SlithyMatt/multi-man ... elbrot.asm

Starting at top left corner, it visits the entire screen (from left to right, then again for the next row), to calculate and modify each attribute color. At every step, it spends some time to calculate the corresponding attribute address on screen.

Why?

It could simply start at attribute address 22528 and increment it at every step.
danboid
Dizzy
Posts: 62
Joined: Sun May 12, 2024 11:16 am

Re: mandelbrot drawing CPU benchmark

Post by danboid »

flatduckrecords wrote: Wed May 15, 2024 12:06 pm It looks like the asm files in the ZXN directory already have the correct SjASMPlus directives, so I was able to assemble just by running the build.sh file, but you could also invoke it directly:

Code: Select all

sjasmplus --lst zxn-mandelbrot.asm
sjasmplus --lst zxn-mandelbrot2.asm
sjasmplus --lst zxn-mandelbrot_127_63_15.asm
sjasmplus --lst zxn-mandelbrot_max_lores.asm
sjasmplus --lst zxn-mandelbrot_max_layer2.asm
If that doesn't work I can share the assembled .nex files.
build.sh file? Which build.sh file are you referring to?

I want to learn how to build this myself. I've just tried using --lst now but I get these errors:

Code: Select all

dan@zbook:~/src/multi-mandlebrot/Z80n$ sjasmplus --lst=mandelbrot.nex mandelbrot.asm
SjASMPlus Z80 Cross-Assembler v1.20.3 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
fixedpt.asm(175): error: Unrecognized instruction: mul d,e
fixedpt.asm(181): error: Unrecognized instruction: mul d,e
fixedpt.asm(186): error: Unrecognized instruction: mul d,e
fixedpt.asm(197): error: Unrecognized instruction: mul d,e
Pass 3 complete
Errors: 4, warnings: 0, compiled: 332 lines, work time: 0.002 seconds
dan@zbook:~/src/multi-mandlebrot/Z80n$ ls -l
total 56
-rw-rw-r-- 1 dan dan  5551 May 15 13:02 fixedpt24.asm
-rw-rw-r-- 1 dan dan  3518 May 15 13:02 fixedpt.asm
-rw-rw-r-- 1 dan dan  4122 May 15 13:02 mandelbrot24.asm
-rw-rw-r-- 1 dan dan  4052 May 15 13:02 mandelbrot.asm
-rw-rw-r-- 1 dan dan 15653 May 15 13:06 mandelbrot.lst
-rw-rw-r-- 1 dan dan 15653 May 15 13:08 mandelbrot.nex
dan@zbook:~/src/multi-mandlebrot/Z80n$ sjasmplus --lst=mandelbrot24.nex mandelbrot24.asm
SjASMPlus Z80 Cross-Assembler v1.20.3 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
fixedpt24.asm(207): error: Unrecognized instruction: mul d,e
fixedpt24.asm(212): error: Unrecognized instruction: mul d,e
fixedpt24.asm(220): error: Unrecognized instruction: mul d,e
fixedpt24.asm(229): error: Unrecognized instruction: mul d,e
fixedpt24.asm(242): error: Unrecognized instruction: mul d,e
fixedpt24.asm(252): error: Unrecognized instruction: mul d,e
fixedpt24.asm(259): error: Unrecognized instruction: mul d,e
fixedpt24.asm(269): error: Unrecognized instruction: mul d,e
Pass 3 complete
Errors: 8, warnings: 0, compiled: 640 lines, work time: 0.011 seconds
Last edited by danboid on Wed May 15, 2024 1:12 pm, edited 1 time in total.
danboid
Dizzy
Posts: 62
Joined: Sun May 12, 2024 11:16 am

Re: mandelbrot drawing CPU benchmark

Post by danboid »

Einar Saukas wrote: Wed May 15, 2024 12:23 pm More like a benchmark of someone's programming skills in various retro computer platforms :)

For instance here:

https://github.com/SlithyMatt/multi-man ... elbrot.asm

Starting at top left corner, it visits the entire screen (from left to right, then again for the next row), to calculate and modify each attribute color. At every step, it spends some time to calculate the corresponding attribute address on screen.

Why?

It could simply start at attribute address 22528 and increment it at every step.
Please share you improved version and tell me how to build it.

Thanks
danboid
Dizzy
Posts: 62
Joined: Sun May 12, 2024 11:16 am

Re: mandelbrot drawing CPU benchmark

Post by danboid »

OK I think I've got them to build OK now

Code: Select all

dan@zbook:~/src/multi-mandlebrot/Z80n$ sjasmplus --zxnext --lst=mandelbrot.nex mandelbrot.asm
SjASMPlus Z80 Cross-Assembler v1.20.3 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
Pass 3 complete
Errors: 0, warnings: 0, compiled: 332 lines, work time: 0.002 seconds
dan@zbook:~/src/multi-mandlebrot/Z80n$ sjasmplus --zxnext --lst=mandelbrot24.nex mandelbrot24.asm
SjASMPlus Z80 Cross-Assembler v1.20.3 (https://github.com/z00m128/sjasmplus)
Pass 1 complete (0 errors)
Pass 2 complete (0 errors)
Pass 3 complete
Errors: 0, warnings: 0, compiled: 640 lines, work time: 0.003 seconds
danboid
Dizzy
Posts: 62
Joined: Sun May 12, 2024 11:16 am

Re: mandelbrot drawing CPU benchmark

Post by danboid »

Nope. That is not correct. When I try running one of those .nex files I get the error

Code: Select all

This is a ve.o file. Please update to the latest .nexload version.
Does anyone use sjasmplus under Linux who can tell me how I should be building these files? sjasmplus does not output a .nex file for me, not that I can see. I'm just told its compiled OK.
User avatar
ParadigmShifter
Dynamite Dan
Posts: 1050
Joined: Sat Sep 09, 2023 4:55 am

Re: mandelbrot drawing CPU benchmark

Post by ParadigmShifter »

You're only outputting a .lst file?

I tried that on my (speccy) code, this is the kind of thing it produces

Code: Select all

# file opened: sheet.asm
  1   0000              ; sjasmplus.exe --sym=out.sym --syntax=f --raw=out.bin sheet.asm
  2   0000
  3   0000              	DEVICE ZXSPECTRUM48
  4   0000
  5   0000              TIMING EQU 1
  6   0000
  7   0000              ORGADDR	EQU #8000
  8   0000
  9   0000              	ORG ORGADDR
 10   8000
 11   8000              	DISPLAY "ORIGIN ", /A, ORGADDR
 12   8000
 13   8000              main:
 14   8000              	IF TIMING
 15   8000 3E 01        	ld a, 1
 16   8002 D3 FE        	out (#fe), a
 17   8004              	ENDIF
 18   8004
which is not executable code.

You probably want something like --raw=out.bin to produce a binary file?

EDIT: Ok you probably need to use SAVENEX at the end of your file but I can't really help with that since I don't know about the Next binary format.
User avatar
flatduckrecords
Manic Miner
Posts: 831
Joined: Thu May 07, 2020 11:47 am
Location: Oban, Scotland
Contact:

Re: mandelbrot drawing CPU benchmark

Post by flatduckrecords »

Ah, I see the problem @danboid, you're looking in the Z80n directory, but those are just partial files, meant to be INCLUDE'd within another asm file.

The directory called zxn is the one you need. That contains the .asm files that can be assembled. The build script is in there as well!
User avatar
Einar Saukas
Bugaboo
Posts: 3213
Joined: Wed Nov 15, 2017 2:48 pm

Re: mandelbrot drawing CPU benchmark

Post by Einar Saukas »

danboid wrote: Wed May 15, 2024 1:11 pm Please share you improved version and tell me how to build it.
Replace file "zxs-mandelbrot.asm" with this:

Code: Select all

   DEVICE ZXSPECTRUM48

   org $8000

start:
   jp init

color_codes:
   db 8,16,24,32,40,48,56,72
   db 80,88,96,104,112,120,0

   include "../Z80/mandelbrot.asm"

ROM_CLS           = $0DAF

COLOR_MAP         = $5800


i_result: db 0

init:
   di
   exx                  ; save hl' register on stack
   push hl              ; to correct return into basic
   call ROM_CLS
   ld bc,0              ; X = 0, Y = 0
   LD DE,COLOR_MAP-1
   PUSH DE              ; SAVE ATTRIBUTE ADDRESS
.loopm:
   call mand_get
   POP DE
   INC DE               ; NEXT ATTRIBUTE ADDRESS
   PUSH DE
   ld hl,color_codes
   add a,l              ; HL = I
   ld l,a
   ld a,(hl)            ; A = color code for I
   ld (de),a            ; set color code
   inc b                ; increment X
   BIT 5,B
   JP Z,.loopm          ; loop until X = width
   ld b,0               ; X = 0
   inc c                ; increment Y
   ld a,MAND_HEIGHT
   cp c
   jp nz,.loopm         ; loop until Y = height
   POP DE               ; DISCARD ATTRIBUTE ADDRESS
   pop hl               ; restore hl' register
   exx                  ; from stack
   ei
   ret


; Deployment
LENGTH      = $ - start

; option 1: tape
   include TapLib.asm
   MakeTape ZXSPECTRUM48, "man48.tap", "man48", start, LENGTH, start

; option 2: snapshot
   SAVESNA "man48.sna", start
All changes in capital letters. Not tested but it should work :)

Based on a quick look at the other files, there's a lot to optimize there too...
danboid
Dizzy
Posts: 62
Joined: Sun May 12, 2024 11:16 am

Re: mandelbrot drawing CPU benchmark

Post by danboid »

flatduckrecords wrote: Wed May 15, 2024 2:25 pm Ah, I see the problem @danboid, you're looking in the Z80n directory, but those are just partial files, meant to be INCLUDE'd within another asm file.

The directory called zxn is the one you need. That contains the .asm files that can be assembled. The build script is in there as well!
That was my problem. I never spotted the zxn dir and presumed it was the z80n dir I was trying the build. Thanks flatduckrecords!

The .asm files in the zxn dir successfully output .nex binaries that actually run and you can build them just by just running `sjasmplus` with no extra options required apart from the name of the .asm file to build.

Easy peasy when you use the right files!
danboid
Dizzy
Posts: 62
Joined: Sun May 12, 2024 11:16 am

Re: mandelbrot drawing CPU benchmark

Post by danboid »

Einar Saukas wrote: Wed May 15, 2024 3:42 pm Replace file "zxs-mandelbrot.asm" with this:

Code: Select all

   DEVICE ZXSPECTRUM48

   org $8000

start:
   jp init

color_codes:
   db 8,16,24,32,40,48,56,72
   db 80,88,96,104,112,120,0

   include "../Z80/mandelbrot.asm"

ROM_CLS           = $0DAF

COLOR_MAP         = $5800


i_result: db 0

init:
   di
   exx                  ; save hl' register on stack
   push hl              ; to correct return into basic
   call ROM_CLS
   ld bc,0              ; X = 0, Y = 0
   LD DE,COLOR_MAP-1
   PUSH DE              ; SAVE ATTRIBUTE ADDRESS
.loopm:
   call mand_get
   POP DE
   INC DE               ; NEXT ATTRIBUTE ADDRESS
   PUSH DE
   ld hl,color_codes
   add a,l              ; HL = I
   ld l,a
   ld a,(hl)            ; A = color code for I
   ld (de),a            ; set color code
   inc b                ; increment X
   BIT 5,B
   JP Z,.loopm          ; loop until X = width
   ld b,0               ; X = 0
   inc c                ; increment Y
   ld a,MAND_HEIGHT
   cp c
   jp nz,.loopm         ; loop until Y = height
   POP DE               ; DISCARD ATTRIBUTE ADDRESS
   pop hl               ; restore hl' register
   exx                  ; from stack
   ei
   ret


; Deployment
LENGTH      = $ - start

; option 1: tape
   include TapLib.asm
   MakeTape ZXSPECTRUM48, "man48.tap", "man48", start, LENGTH, start

; option 2: snapshot
   SAVESNA "man48.sna", start
All changes in capital letters. Not tested but it should work :)

Based on a quick look at the other files, there's a lot to optimize there too...
Thanks but I'm only really bothered about the Next version and it seems you optimsed the Speccy 48k version.
danboid
Dizzy
Posts: 62
Joined: Sun May 12, 2024 11:16 am

Re: mandelbrot drawing CPU benchmark

Post by danboid »

When I run one of these fractal drawing .nex binaries, is there a key combo that will let me return to the zxn command prompt when its finished drawing or is rebooting my only option?

It could do with printing out the time took to draw the fractal. That could be my first z80 asm project if it doesn't already do that already.
User avatar
Einar Saukas
Bugaboo
Posts: 3213
Joined: Wed Nov 15, 2017 2:48 pm

Re: mandelbrot drawing CPU benchmark

Post by Einar Saukas »

danboid wrote: Wed May 15, 2024 6:40 pm Thanks but I'm only really bothered about the Next version and it seems you optimsed the Speccy 48k version.
That's the file I indicated in my first post.

You could have mentioned you were not interested in this file, when you asked for the improved version of this file! :) :) :)
Post Reply