************************************************ * Mandelbrot computing routines for Color Computer 3 * copyright Chris Lomont 2006 www.lomont.org * ************************************************ ************************************************ * MandelbrotZoom - compute zoom internal constants * for zooming in on current region * REGX x1 coord 0-319 upper left * REGU x2 coord 0-319 lower right * REGA y1 coord 0-199 upper left * REGB y2 coord 0-199 lower right * REGY iteration count max * Registers changed: None ************************************************ MandelbrotZoom pshs u,y,x,b,a u:6,s y:4,s x:2,s b:1,s a:,s cmpb ,s bls > out of bounds cmpu 2,s bls > out of bounds ldx #MandelItMx sty ,x store iteration count * compute new x shift clra scale x point ldx 2,s x1 value lbsr MandelbrotScale ldx #MandelTemp ldy #MandelXSh lbsr FPCopy store new x shift * compute new y shift ldb ,s tfr d,x y1 value inca scale y point lbsr MandelbrotScale ldx #MandelTemp ldy #MandelYSh lbsr FPCopy store new y shift * compute new x scale ldx #MandelDiv319 ldy #MandelXSc tfr y,u lbsr FPMul do in this order to prevent overflow ldd 6,s get x2 subd 2,s subtract x1 ldx #MandelTemp lbsr FPClear std ,x (x2-x1)/256 as fixed point lbsr FPMul * compute new y scale ldx #MandelDiv199 ldy #MandelYSc tfr y,u lbsr FPMul do in this order to prevent overflow clra ldb 1,s get y2 subb ,s subtract y1 ldx #MandelTemp lbsr FPClear std ,x (y2-y1)/256 as fixed point lbsr FPMul ! puls u,y,x,b,a rts MandelDiv319 fcb 0,205, 113, 39 fixed point value for 256/319 MandelDiv199 fcb 1, 73, 83, 158 fixed point value for 256/199 ************************************************ * MandelbrotReset - resets the viewing region * to the outermost view (standard view) * Registers changed: None ************************************************ MandelbrotReset * mostly just copy over a lot of scaling constants pshs x,y ldx #MandelXScDef ldy #MandelXSc lbsr FPCopy ldx #MandelYScDef ldy #MandelYSc lbsr FPCopy ldx #MandelXShDef ldy #MandelXSh lbsr FPCopy ldx #MandelYShDef ldy #MandelYSh lbsr FPCopy puls x,y rts * constants that define the outermost view MandelXScDef fcb 2,104,83,118 (3/319)*256 in FP x scale MandelYScDef fcb 2,146,167,60 (2/199)*256 in FP y scale MandelXShDef fcb $FE,0,0,0 -2 in FP x shift MandelYShDef fcb $FF,0,0,0 -1 in FP y shift ************************************************ * MandelbrotScale - convert a pixel coord to a * complex plane coord - todo - REGU is dest makes better routine? * REGX - value to scale as an integer * REGA - 0 means scale X, 1 means scale Y * final value stored in MandelTemp * Registers changed: None ************************************************ MandelbrotScale pshs x,y,u,d tfr x,y ldx #MandelTemp lbsr FPClear clear it sty MandelTemp set pixel pos/256 tfr x,y y point to temp tsta beq scalex@ cmpa #1 bne exit@ scaley@ ldx #MandelYSc yscale ldu #MandelTemp lbsr FPMul tfr u,x ldy #MandelYSh yshift lbsr FPAdd bra exit@ scalex@ ldx #MandelXSc xscale ldu #MandelTemp lbsr FPMul tfr u,x ldy #MandelXSh xshift lbsr FPAdd exit@ puls x,y,u,d rts ************************************************ * MandelbrotComputePoint - Mandelbrot point computation * REGX x coord 0-319 * REGY y coord 0-199 * returns REGD is number of color value 0 on up * uses internal values to detemine view * Registers changed: REGD ************************************************ * mandelbrot drawn using current scaling, defaults to [-2,1]x[-1,1] MandelbrotComputePoint pshs u,y,x u:4,s y:2,s x:,s * x = x0 = x co-ordinate of pixel * y = y0 = y co-ordinate of pixel clra prepare to position x bsr MandelbrotScale position x ldx #MandelTemp copy over ldy #MandelX lbsr FPCopy ldy #MandelX0 lbsr FPCopy inca prepare to position y ldx 2,s get y value bsr MandelbrotScale position y ldx #MandelTemp copy over ldy #MandelY lbsr FPCopy ldy #MandelY0 lbsr FPCopy * x2 = x*x * y2 = y*y ldx #MandelX initialize the squares - todo - compact with below tfr x,y ldu #MandelX2 lbsr FPMul ldx #MandelY tfr x,y ldu #MandelY2 lbsr FPMul * iteration = 1 * maxiteration = uses internal constant ldd #1 std MandelIt * std ,x todo - error? * while ( x2 + y2 < (2*2) AND iteration < maxiteration ) { mloop ldx #MandelX2 ldy #MandelY2 ldu #MandelTemp lbsr FPAdd todo - can compare with top byte in MandelTemp >= 4 now :) tfr u,x ldy #FPNegFour todo - can check this with highest FP byte lbsr FPAdd lda ,u get highest bit, see if positive bita #$80 beq mdone jump out ldd MandelIt cmpd MandelItMx bge mdone if too many iterations, bail out * iteration = iteration + 1 * incd todo - remove - this is 6309 only! * addb #1 todo - faster for addd? * adca #0 addd #1 std MandelIt * y = 2*x*y + y0 ldx #MandelX ldy #MandelY ldu #MandelTemp lbsr FPMul tfr u,x ldy #FPTwo ldu #MandelY lbsr FPMul todo- make a mul by two routine - faster tfr u,x ldy #MandelY0 lbsr FPAdd * x = x2 - y2 + x0 ldx #MandelY2 lbsr FPNeg ldy #MandelX2 ldu #MandelX lbsr FPAdd tfr u,x ldy #MandelX0 lbsr FPAdd * x2 = x*x * y2 = y*y ldx #MandelX tfr x,y ldu #MandelX2 lbsr FPMul ldx #MandelY tfr x,y ldu #MandelY2 lbsr FPMul lbra mloop * if ( iteration == maxiteration ) * color = black * else * color = iteration mdone ldd MandelIt cmpd MandelItMx bne @clrok ldd #0 @clrok puls x,y,u rts MandelX fcb 0,0,0,0 current iterate MandelY fcb 0,0,0,0 MandelX2 fcb 0,0,0,0 square of iterate MandelY2 fcb 0,0,0,0 MandelX0 fcb 0,0,0,0 point to add each pass MandelY0 fcb 0,0,0,0 MandelTemp fcb 0,0,0,0 temp space MandelIt fcb 0,0 iteration count MandelItMx fcb 0,50 max iter iteration count 50 default * some constants for computations MandelXSc fcb 2,104,83,118 (3/319)*256 in FP x scale MandelYSc fcb 2,146,167,60 (2/199)*256 in FP y scale MandelXSh fcb $FE,0,0,0 -2 in FP x shift MandelYSh fcb $FF,0,0,0 -1 in FP y shift * end - Mandelbrot.asm