home *** CD-ROM | disk | FTP | other *** search
- ; FRACASM.ASM - Assembler subroutines for fractals.c
-
- ; required for compatibility if Turbo ASM
- IFDEF ??version
- MASM51
- QUIRKS
- EMUL
- ENDIF
-
- .MODEL medium,c
-
- .8086
-
- ; these must NOT be in any segment!!
- ; this get's rid of TURBO-C fixup errors
- extrn multiply:far ; this routine is in 'general.asm'
-
- .data
-
- extrn lold:qword, lnew:qword ; each defined as LCMPLX in fractals.c
- extrn ltempsqrx:dword ; for fractals.c
- extrn ltempsqry:dword ; for fractals.c
- extrn lmagnitud:dword ; for fractals.c
- extrn llimit:dword ; from calcfrac.c
- extrn llimit2:dword ; from calcfrac.c
- extrn bitshift:word ; fudgefactor for integer math
- extrn overflow:word ; error from integer math
-
- .code
-
-
- public longbailout
-
- longbailout proc
- ;
- ; equivalent to the C code:
- ; ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
- ; lmagnitud = ltempsqrx + ltempsqry;
- ; if (lmagnitud >= llimit || lmagnitud < 0 || labs(lnew.x) > llimit2
- ; || labs(lnew.y) > llimit2 || overflow)
- ; { overflow=0; return(1); }
- ; lold = lnew;
- ; return(0);
- ;
- ; ltempsqrx = lsqr(lnew.x);
- push bitshift
- push WORD PTR lnew+2
- push WORD PTR lnew
- push WORD PTR lnew+2
- push WORD PTR lnew
- call FAR PTR multiply
- mov WORD PTR ltempsqrx,ax
- mov WORD PTR ltempsqrx+2,dx
- ; ltempsqry = lsqr(lnew.y);
- push bitshift
- push WORD PTR lnew+6
- push WORD PTR lnew+4
- push WORD PTR lnew+6
- push WORD PTR lnew+4
- call FAR PTR multiply
- add sp,20
- mov WORD PTR ltempsqry,ax
- mov WORD PTR ltempsqry+2,dx
- ; lmagnitud = ltempsqrx + ltempsqry;
- add ax,WORD PTR ltempsqrx
- adc dx,WORD PTR ltempsqrx+2
- mov WORD PTR lmagnitud,ax
- mov WORD PTR lmagnitud+2,dx
- ; if (lmagnitud >= llimit
- cmp dx,WORD PTR llimit+2
- jl chkvs0
- jg bailout
- cmp ax,WORD PTR llimit
- jae bailout
- ; || lmagnitud < 0
- chkvs0: or dx,dx
- js bailout
- ; || labs(lnew.x) > llimit2
- mov ax,WORD PTR lnew
- mov dx,WORD PTR lnew+2
- or dx,dx
- jge lnewx
- neg ax
- adc dx,0
- neg dx
- lnewx: cmp dx,WORD PTR llimit2+2
- jl chklnewy
- jg bailout
- cmp ax,WORD PTR llimit2
- ja bailout
- ; || labs(lnew.y) > llimit2
- chklnewy:
- mov ax,WORD PTR lnew+4
- mov dx,WORD PTR lnew+6
- or dx,dx
- jge lnewy
- neg ax
- adc dx,0
- neg dx
- lnewy: cmp dx,WORD PTR llimit2+2
- jl chkoflow
- jg bailout
- cmp ax,WORD PTR llimit2
- ja bailout
- ; || overflow)
- chkoflow:
- cmp overflow,0
- jne bailout
- ; else {
- ; lold = lnew;
- mov ax,WORD PTR lnew
- mov dx,WORD PTR lnew+2
- mov WORD PTR lold,ax
- mov WORD PTR lold+2,dx
- mov ax,WORD PTR lnew+4
- mov dx,WORD PTR lnew+6
- mov WORD PTR lold+4,ax
- mov WORD PTR lold+6,dx
- ; return(0); }
- sub ax,ax
- ret
- bailout:
- ; { overflow=0; return(1); }
- mov overflow,0
- mov ax,1
- ret
- longbailout endp
-
-
- ; Fast fractal orbit calculation procs for Fractint.
- ; By Chuck Ebbert CIS: (76306,1226)
- ;
- ; FManOWarfpFractal()
- ; FJuliafpFractal()
- ; FBarnsley1FPFractal()
- ; FBarnsley2FPFractal()
- ; FLambdaFPFractal()
- ;
- ; asmfloatbailout() -- bailout proc (NEAR proc used by above)
- ; NOTE: asmfloatbailout() modifies SI and DI.
- ;
- ; These will only run on machines with a 287 or a 387 (and a 486 of course.)
- ;
- ; Some of the speed gains from this code are due to the storing of the NPU
- ; status word directly to the AX register. FRACTINT will use these
- ; routines only when it finds a 287 or better coprocessor installed.
-
- .286
- .287
-
- .data
-
- extrn new:qword, old:qword, tmp:qword
- extrn rqlim:qword, magnitude:qword, tempsqrx:qword, tempsqry:qword
- extrn cpu:word, fpu:word, floatparm:word
-
- .code
-
- ; px,py = floatparm->x,y
- ; ox,oy = oldx,oldy
- ; nx,ny = newx,newy
- ; nx2,ny2 = newxsquared,newysquared
- ; tx,ty = tempx, tempy (used in lambda)
-
- FManOWarfpFractal proc uses si di
- ; From Art Matrix via Lee Skinner
- fld tempsqrx ; ox2
- fsub tempsqry ; ox2-oy2
- mov bx,floatparm
- fadd tmp ; ox2-oy2+tx
- fadd qword ptr [bx] ; newx
- fld old ; oldx newx
- fmul old+8 ; oldx*oldy newx
- fadd st,st ; oldx*oldy*2 newx
- fadd tmp+8 ; oldx*oldy*2+tmp.y newx
- fadd qword ptr [bx+8] ; newy newx
- mov si,offset old ; tmp=old
- mov di,offset tmp
- mov ax,ds
- mov es,ax
- mov cx,8
- rep movsw
- call near ptr asmfloatbailout
- ret
- FManOWarfpFractal endp
-
- FJuliafpFractal proc uses si di
- ; Julia/Mandelbrot floating-point orbit function.
- fld tempsqrx
- fsub tempsqry
- mov bx,floatparm
- fadd qword ptr [bx] ;/* add floatparm->x */
- fld qword ptr old ;/* now get 2*x*y+floatparm->y */
- fmul qword ptr old+8
- fadd st,st
- fadd qword ptr [bx+8] ; add floatparm->y
- call near ptr asmfloatbailout
- ret
- FJuliafpFractal endp
-
- FBarnsley1FPFractal proc uses si di
- ; From Fractals Everywhere by Michael Barnsley
- mov bx,floatparm
- fld qword ptr [bx] ;/* STACK: px */
- fld qword ptr [bx+8] ;/* py px */
- fld qword ptr old ;/* ox py px */
- ftst ;/*** we will want this later */
- fstsw ax ;/*** 287 or better only */
- fld old+8 ;/* oy ox py px */
- fld st(1) ;/* ox oy ox py px */
- fmul st,st(4) ;/* ox*px oy ox py px */
- fld st(1) ;/* oy ox*px oy ox py px */
- fmul st,st(4) ;/* oy*py ox*px oy ox py px */
- fsub ;/* (ox*px-oy*py) oy ox py px */
- fxch ;/* oy (oxpx-oypy) ox py px */
- fmul st,st(4) ;/* oy*px (oxpx-oypy) ox py px */
- fxch st(2) ;/* ox (oxpx-oypy) oy*px py px */
- fmul st,st(3) ;/* ox*py (oxpx-oypy) oy*px py px */
- faddp st(2),st ;/* oxpx-oypy oypx+oxpy py px */
- sahf ;/*** use the saved status (finally) */
- jb BFPM1add
- fsubrp st(3),st ;/* oypx+oxpy py nx */
- fsubr ;/* ny nx */
- jmp short BFPM1cont
- BFPM1add:
- faddp st(3),st ;/* oypx+oxpy py nx */
- fadd ;/* ny nx */
- BFPM1cont:
- call near ptr asmfloatbailout
- ret
- FBarnsley1FPFractal endp
-
- FBarnsley2FPFractal proc uses si di
- ; Also from Fractals Everywhere
- mov bx,floatparm
- fld qword ptr [bx] ;/* STACK: px */
- fld qword ptr [bx+8] ;/* py px */
- fld qword ptr old ;/* ox py px */
- fld qword ptr old+8 ;/* oy ox py px */
- fld st(1) ;/* ox oy ox py px */
- fmul st,st(4) ;/* ox*px oy ox py px */
- fld st(1) ;/* oy ox*px oy ox py px */
- fmul st,st(4) ;/* oy*py ox*px oy ox py px */
- fsub ;/* (ox*px-oy*py) oy ox py px */
- fxch st(2) ;/* ox oy (oxpx-oypy) py px */
- fmul st,st(3) ;/* ox*py oy (oxpx-oypy) py px */
- fxch ;/* oy ox*py (oxpx-oypy) py px */
- fmul st,st(4) ;/* oy*px ox*py (oxpx-oypy) py px */
- fadd ;/* oypx+oxpy oxpx-oypy py px */
- ftst
- fstsw ax ;/* 287 or better only */
- sahf
- jb BFPM2add
- fsubrp st(2),st ;/* oxpx-oypy ny px */
- fsubrp st(2),st ;/* ny nx */
- jmp short BFPM2cont
- BFPM2add:
- faddp st(2),st ;/* oxpx-oypy ny px */
- faddp st(2),st ;/* ny nx */
- BFPM2cont:
- call near ptr asmfloatbailout
- ret
- FBarnsley2FPFractal endp
-
- FLambdaFPFractal proc uses si di
- ; tempsqrx and tempsqry can be used -- the C code doesn't use them!
- fld tempsqry ;oy2
- fsub tempsqrx ;oy2-ox2
- fld old ;ox oy2-ox2
- fadd st(1),st ;ox tx=ox+oy2-ox2
- fadd st,st ;2ox tx
- fld1 ;1 2ox tx
- fsubr ;(1-2ox) tx
- fmul old+8 ;ty=oy(1-2ox) tx
- fld st(1) ;tx ty tx -- duplicate these now
- fld st(1) ;ty tx ty tx
- mov bx,floatparm
- fld qword ptr [bx+8] ;py ty tx ty tx -- load y first
- fld qword ptr [bx] ;px py ty tx ty tx
- fmul st(5),st ;px py ty tx ty pxtx
- fmulp st(4),st ;py ty tx pxty pxtx
- fmul st(2),st ;py ty pytx pxty pxtx
- fmul ;pyty pytx pxty pxtx
- fsubp st(3),st ;pytx pxty nx=pxtx-pyty
- fadd ;ny=pxty+pytx nx
- call near ptr asmfloatbailout
- ret
- FLambdaFPFractal endp
-
- asmfloatbailout proc near
- ; called with new.y and new.x on stack and clears the stack
- ; destroys SI and DI: caller must save them
- fst qword ptr new+8
- fmul st,st ;/* ny2 nx */
- fst tempsqry
- fxch ;/* nx ny2 */
- fst qword ptr new
- fmul st,st ;/* nx2 ny2 */
- fst tempsqrx
- fadd
- fst magnitude
- fcomp rqlim ;/*** stack is empty */
- fstsw ax ;/*** 287 and up only */
- sahf
- jae bailout
- mov si,offset new
- mov di,offset old
- mov ax,ds
- mov es,ax
- mov cx,8
- rep movsw
- xor ax,ax
- ret
- bailout:
- mov ax,1
- ret
- asmfloatbailout endp
-
-
- .8086
- .8087
-
- end
-