* SManCP * By David M. McKinstry. * This version completed 6/13/89 * This is copyrighted by the author and not to be used in any commerical * application (excepting Amiga demonstrations) with out his permission. * However, it may be freely used any duplicated for any non-commercial * applications. INCLUDE "exec/types.i" ;Needed for SOFFSET macro INCLUDE "graphics/rastport.i" INCLUDE "intuition/intuition.i" mc68881 XDEF _FuncFind XDEF _ConExt XREF _LVOSetAPen XREF _LVOWritePixel XREF _GfxBase XREF _LVOSetAPen XREF _LVOWritePixel XREF _Factor XREF _XCenter XREF _YCenter XREF _xtemp XREF _ytemp XREF _LacMod XREF _IntWindow XREF _CWRast XREF _SWidth XREF _SHeight XREF _S1Width XREF _S1Height XREF _CurCnt XREF _MaxCnt PlotIt: move.l _CurCnt,d0 ;Get Mandelbrot count cmp.l #$FFFF,d0 ;See if indicated as M.B. It won't be this big bne.s MandOut move.l #15,d0 bra.s SetC MandOut: ext.l d0 lsr.l #2,d0 add.l #1,d0 SetC: move.l _CWRast,a1 move.b d0,rp_FgPen(a1) move.l _ytemp,d1 cmp.l #49,d1 bge.s OKay ;Use my SetPix if below Menus, movem.l d0-d7/a0-a6,-(a7) ;Otherwise use WritePixel. move.l a1,-(a7) ;Save raster port move.l _GfxBase,a6 jsr _LVOSetAPen(a6) move.l _IntWindow,a0 move.w wd_MouseY(a0),d0 cmp.w #49,d0 blt.s IntSet ;Mouse in menu region cmp.l #10,_ytemp ;See if y less than 12 ble.s IntSet bra.s MySet IntSet: move.l _xtemp,d0 move.l _ytemp,d1 move.l (a7)+,a1 jsr _LVOWritePixel(a6) movem.l (a7)+,d0-d7/a0-a6 rts MySet: move.l (a7)+,a1 ;Recover Raster port movem.l (a7)+,d0-d7/a0-a6 OKay: move.l _xtemp,d0 bsr SetOne rts SetOne: cmp.w _SWidth,d0 bge.s SetNot cmp.w _SHeight,d1 bgt.s SetNot tst.l d1 ;See if - bmi.s SetNot bsr SetPix SetNot: rts *SetPix has inputs of d0.w for x, d1.w for y, and a3 for the video pointer * Registers affected include d1, d2, and a0. It returns with the address * of the pixel in a0 and the bit to be set or cleared in d1 SetPix: movem.l d0-d3/a0-a2,-(a7) move.b rp_FgPen(a1),d3 ;Get mask for rastport move.l rp_BitMap(a1),a1 ;Get pointer to bitmap move.l a1,a2 ;Save bit map pointer in a2 addq.l #bm_Planes,a1 ;Get pointer to planes move.w d1,d2 ;See if y is - and get into d2 bmi.s SetNo ;Don't set if negative cmp.w (_S1Height+2),d1 bgt.s SetNo move.w d1,d2 ;y is in d2 move.w d0,d1 ;See if x is negative bmi.s SetNo ;Don't set if is cmp.w (_S1Width+2),d0 bgt.s SetNo ;bcc.s SetNo ;If no carry then too big move.l d2,d1 ;Save y in d1 mulu _SWidth,d1 ;Get Screen width times y add.l d0,d1 ;Add in x coordinate lsr.l #3,d1 ;d1 is x/8 move.l d1,d2 move.w d0,d1 ;d1 is x eori.w #7,d1 ;Toggle lowest 3 bits. andi.w #7,d1 ;Get 7 - x(mod 8) ext.l d3 move.l d3,d0 ;Move pen color into d0 move.b bm_Depth(a2),d3 ;Get depth in d3 SetPln: move.l (a1)+,a0 ;Get pointer to bit plane adda.l d2,a0 ;Add in offset btst #0,d0 ;See if 1st color beq.s NoOne bset d1,(a0) ;Set bit 7-x(mod8) bra.s PlnOne NoOne: bclr d1,(a0) PlnOne: asr.l #1,d0 ;Move next bit in color down. sub.b #1,d3 ;See if all planes done. bne.s SetPln SetNo: movem.l (a7)+,d0-d3/a0-a2 rts * Convert relevant double precision values from main to extended precision. _ConExt: fmove.x fp0,-(a7) fmove.d _Factor,fp0 fmove.x fp0,Factor move.l #2,d0 fmove.l d0,fp0 fmove.x fp0,Two fmove.x Factor,fp0 fmul.x Two,fp0 fmul.x fp0,fp0 fmove.x fp0,Limit fmove.d _XCenter,fp0 fmove.x fp0,XCenter fmove.d _YCenter,fp0 fmove.x fp0,YCenter fmove.x (a7)+,fp0 rts nop nop nop nop nop nop nop nop lea Limit,a0 _FuncFind: bsr FncFnd move.l d7,_CurCnt bsr PlotIt rts FncFnd: fmove.x Two,fp7 fmove.x Factor,fp6 move.l _xtemp,d0 move.l _ytemp,d1 tst.w _LacMod bne.s IsLace lsl.l #1,d1 ;If non-interlace, double y. IsLace: fmove.l d0,fp0 fmove.l d1,fp1 fsub.x XCenter,fp0 fsub.x YCenter,fp1 bsr Mand rts Mand: move.l #0,d7 ;Initialize counter fmove.l d7,fp2 ;Place 0 in Zr fmove.x fp2,fp3 ;Same for Zi ZConv: bsr.s ZFind ;Get next value for Zr and Zi cmp.l _MaxCnt,d7 ;See if to be assumed within Mandelbrot set bgt.s LimCnt bra.s ZConv LimCnt: move.l #$FFFF,d7 ;Indicate it is part of Mandelbrot NotMand: rts ZFind: fmove.x fp2,fp4 ;Get current Zr into temporary fmove.x fp3,fp5 ;Do same for Zi fmul.x fp4,fp4 ;Find Zr^2 fmul.x fp5,fp5 ;Find Zi^2 fmove.x fp5,-(a7) ;Save Zi^2 on stack fadd.x fp4,fp5 ;Find z-squared fcmp.x Limit,fp5 ;See if > 2^2 (i.e. is |Z|>2?) fbgt TooBig ;If so extablish count to failure fmove.x (a7)+,fp5 ;Recover Zi^2 fsub.x fp5,fp4 ;Find Zr^2 - Zi^2 fdiv.x fp6,fp4 ;Divide by factor to get part of new Zr fadd.x fp0,fp4 ;Find New Zr fmul.x fp2,fp3 ;Find original Zi*Zr fmul.x fp7,fp3 ;Find 2*Zi*Ze fdiv.x fp6,fp3 ;Divide by Factor fadd.x fp1,fp3 ;Add in original Zi to get new Zi fmove.x fp4,fp2 ;and get new Zr into fp2 addq.l #1,d7 ;Increment counter rts TooBig: fmove.x (a7)+,fp5 ;Recover fp5 to balance stack fmove.x fp2,fp5 ;See if fp5 really needed addq.l #4,a7 ;Balance stack for return from ZFind bra.s NotMand ;Back to Main dseg Limit: ds.l 3 Factor: ds.l 3 Two: ds.l 3 XCenter: ds.l 3 YCenter: ds.l 3 END