# CodeWalrus

## Development => Calculators => Calc Projects, Programming & Tutorials => Topic started by: Zeda on June 26, 2018, 12:26:08 am

Title: Mandelbrot Set, Floatlib
Post by: Zeda on June 26, 2018, 12:26:08 am
A while ago I made Floatlib, an app that contained a bunch of Z80 single-precision floating point routines (as well as a few other helpful routines). My intent was for my own on-calc programming, so it includes in-app documentation. Anyways, I got bored and decided to make a program that draws the Mandelbrot Set as kind of an example. The program requires Floatlib to be on your calc, but the source is:
Code: [Select]
`#include "header.z80"cx   = varscy   = vars+4delta= vars+8zx   = vars+12zy   = vars+16zx2  = vars+20zy2  = vars+24x    = vars+28y    = vars+29bufptr=vars+30mask = vars+32lcd_y= vars+33tmp  = vars+34gbuf = 9340hmaxiter=16start:    in a,(2)    add a,a    sbc a,a    and 3    out (20h),a    call init   ;initialize keyboard, LCD, variablesforx:    ld a,64     ;set Y counter to 64    ld (y),a    ffmov(cy_init,cy)    ffmov(delta_init,delta)fory:    in a,(1)    ;poll the keyboard for [Clear]    and 40h    ret z    in a,(4)    ;poll for [ON]    and 8    ret z    ffmov(cx,zx)    ffmov(cy,zy)    fmul(zx,zx,zx2)    fmul(zy,zy,zy2)    ld a,maxiter    jp endwhilestartwhile:    fmul(zx,zy,zy)    ld hl,zy+3      ;multiply zy by 2 by incrementing the exponent. No worries of overflow, so we can do this cheaply    inc (hl)    fadd(cy,zy,zy)    fsub(zx2,zy2,zx)    fadd(cx,zx,zx)        fmul(zx,zx,zx2)    fmul(zy,zy,zy2)endwhile:    dec a    jr z,plotcalc    fadd(zx2,zy2,tmp)    ;fcmp(tmp,four)    ld h,a    ld a,(tmp+3)       ;check if tmp>=4. This happens if and only if the exponent of tmp is 82h or higher.    cp 82h    ld a,h    jr c,startwhileplotcalc:    or a            ;plot the pixel if counter reached zero    ld a,(mask)    ld hl,(bufptr)    jr nz,\$+5    or (hl)    jr \$+4    cpl    and (hl)    ld (hl),a    out (17),a    ld de,12    add hl,de    ld (bufptr),hl    fadd(cy,delta,cy)    ld hl,y    dec (hl)    jp nz,fory    fadd(cx,delta,cx)    ld hl,(bufptr)    ld a,(mask)    dec h    dec h    dec h    rrca    ld (mask),a    jr nc,+_    inc l    ld a,(lcd_y)    inc a    out (16),a    cp 2Ch    ld (lcd_y),a_:    ld (bufptr),hl    ld hl,x    dec (hl)    jp nz,forx        retinit:    di    ld a,80h        ;Program the LCD to move the index to the top    out (16),a    ;ld a,80h       ;load the mask for the pixel data. Commented since 'a' is already 80h    ld (mask),a    ld hl,gbuf      ;load the ptr to the actual pixel data    ld (bufptr),hl    ld a,96           ;set X counter    ld (x),a    ld hl,(cx_init) \ ld (cx),hl     ;load the starting value for cx    ld hl,(cx_init+2) \ ld (cx+2),hl    ld a,\$FD        ;Program the keyboard to only poll for keys in the [Enter] through [Clear] range    out (1),a    ld a,20h    ld (lcd_y),a    out(16),a    xor a    ld hl,gbuf    ld (hl),a    ld de,gbuf+1    ld bc,767    ldir    retcx_init:    .db \$00,\$00,\$80,\$81 ;-2.0;    .db \$00,\$00,\$80,\$80 ;-1.0;    .db \$51,\$D6,\$56,\$7E ;.41960384;    .db \$00,\$00,\$A0,\$80 ;-1.25cy_init:;    .db \$00,\$00,\$80,\$81 ;-2.0    .db \$00,\$00,\$80,\$80 ;-1.0;    .db \$7C,\$AA,\$48,\$7D ;.19596284;    .db \$00,\$00,\$80,\$7E ;-.25;48aa7Cdelta_init:;    .db \$00,\$00,\$00,\$7C ;.0625    .db \$00,\$00,\$00,\$7B ;.03125;    .db \$1b,\$29,\$1d,\$73 ;.00007494;    .db \$00,\$00,\$00,\$79 ;1/128.echo "Size: ",\$-\$9D95," bytes"`It is 386 bytes and I think it's reasonably fast for using floating point operations instead of integer or fixed-point arithmetic.

I also made a stand-alone Mandelbrot Set Explorer (https://www.ticalc.org/archives/files/fileinfo/465/46536.html) a few years ago, which I think is a lot cooler, but is 1647 bytes and you can't achieve as much of a zoom (this float-based program allows about 500x greater zoom). Then again, the explorer allows you to navigate the Mandelbrot set, zoom in and out, and change how many iterations are used, while the Floatlib one just draws a fixed image (though you can change the source and recompile).