home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / fractint / fras1611.zip / FRACSUBA.ASM < prev    next >
Assembly Source File  |  1991-04-09  |  8KB  |  325 lines

  1. ;    FRACASM.ASM - Assembler subroutines for fractals.c
  2.  
  3. ;             required for compatibility if Turbo ASM
  4. IFDEF ??version
  5. MASM51
  6. QUIRKS
  7. EMUL
  8. ENDIF
  9.  
  10. .MODEL    medium,c
  11.  
  12. .8086
  13.  
  14.     ; these must NOT be in any segment!!
  15.     ; this get's rid of TURBO-C fixup errors
  16.     extrn    multiply:far        ; this routine is in 'general.asm'
  17.  
  18. .data
  19.  
  20.     extrn    lold:qword, lnew:qword    ; each defined as LCMPLX in fractals.c
  21.     extrn    ltempsqrx:dword     ; for fractals.c
  22.     extrn    ltempsqry:dword     ; for fractals.c
  23.     extrn    lmagnitud:dword     ; for fractals.c
  24.     extrn    llimit:dword        ; from calcfrac.c
  25.     extrn    llimit2:dword        ; from calcfrac.c
  26.     extrn    bitshift:word        ; fudgefactor for integer math
  27.     extrn    overflow:word        ; error from integer math
  28.  
  29. .code
  30.  
  31.  
  32.     public    longbailout
  33.  
  34. longbailout    proc
  35. ;
  36. ; equivalent to the C code:
  37. ;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
  38. ;  lmagnitud = ltempsqrx + ltempsqry;
  39. ;  if (lmagnitud >= llimit || lmagnitud < 0 || labs(lnew.x) > llimit2
  40. ;     || labs(lnew.y) > llimit2 || overflow)
  41. ;           { overflow=0; return(1); }
  42. ;  lold = lnew;
  43. ;  return(0);
  44. ;
  45. ;  ltempsqrx = lsqr(lnew.x);
  46.     push    bitshift
  47.     push    WORD PTR lnew+2
  48.     push    WORD PTR lnew
  49.     push    WORD PTR lnew+2
  50.     push    WORD PTR lnew
  51.     call    FAR PTR multiply
  52.     mov    WORD PTR ltempsqrx,ax
  53.     mov    WORD PTR ltempsqrx+2,dx
  54. ;  ltempsqry = lsqr(lnew.y);
  55.     push    bitshift
  56.     push    WORD PTR lnew+6
  57.     push    WORD PTR lnew+4
  58.     push    WORD PTR lnew+6
  59.     push    WORD PTR lnew+4
  60.     call    FAR PTR multiply
  61.     add    sp,20
  62.     mov    WORD PTR ltempsqry,ax
  63.     mov    WORD PTR ltempsqry+2,dx
  64. ;  lmagnitud = ltempsqrx + ltempsqry;
  65.     add    ax,WORD PTR ltempsqrx
  66.     adc    dx,WORD PTR ltempsqrx+2
  67.     mov    WORD PTR lmagnitud,ax
  68.     mov    WORD PTR lmagnitud+2,dx
  69. ;  if (lmagnitud >= llimit
  70.     cmp    dx,WORD PTR llimit+2
  71.     jl    chkvs0
  72.     jg    bailout
  73.     cmp    ax,WORD PTR llimit
  74.     jae    bailout
  75. ;   || lmagnitud < 0
  76. chkvs0: or    dx,dx
  77.     js    bailout
  78. ;   || labs(lnew.x) > llimit2
  79.     mov    ax,WORD PTR lnew
  80.     mov    dx,WORD PTR lnew+2
  81.     or    dx,dx
  82.     jge    lnewx
  83.     neg    ax
  84.     adc    dx,0
  85.     neg    dx
  86. lnewx:    cmp    dx,WORD PTR llimit2+2
  87.     jl    chklnewy
  88.     jg    bailout
  89.     cmp    ax,WORD PTR llimit2
  90.     ja    bailout
  91. ;   || labs(lnew.y) > llimit2
  92. chklnewy:
  93.     mov    ax,WORD PTR lnew+4
  94.     mov    dx,WORD PTR lnew+6
  95.     or    dx,dx
  96.     jge    lnewy
  97.     neg    ax
  98.     adc    dx,0
  99.     neg    dx
  100. lnewy:    cmp    dx,WORD PTR llimit2+2
  101.     jl    chkoflow
  102.     jg    bailout
  103.     cmp    ax,WORD PTR llimit2
  104.     ja    bailout
  105. ;   || overflow)
  106. chkoflow:
  107.     cmp    overflow,0
  108.     jne    bailout
  109. ;  else {
  110. ;  lold = lnew;
  111.     mov    ax,WORD PTR lnew
  112.     mov    dx,WORD PTR lnew+2
  113.     mov    WORD PTR lold,ax
  114.     mov    WORD PTR lold+2,dx
  115.     mov    ax,WORD PTR lnew+4
  116.     mov    dx,WORD PTR lnew+6
  117.     mov    WORD PTR lold+4,ax
  118.     mov    WORD PTR lold+6,dx
  119. ;  return(0); }
  120.     sub    ax,ax
  121.     ret
  122. bailout:
  123. ;  { overflow=0; return(1); }
  124.     mov    overflow,0
  125.     mov    ax,1
  126.     ret
  127. longbailout    endp
  128.  
  129.  
  130. ;  Fast fractal orbit calculation procs for Fractint.
  131. ;  By Chuck Ebbert   CIS: (76306,1226)
  132. ;
  133. ;    FManOWarfpFractal()
  134. ;    FJuliafpFractal()
  135. ;    FBarnsley1FPFractal()
  136. ;    FBarnsley2FPFractal()
  137. ;    FLambdaFPFractal()
  138. ;
  139. ;    asmfloatbailout()     -- bailout proc (NEAR proc used by above)
  140. ;        NOTE: asmfloatbailout() modifies SI and DI.
  141. ;
  142. ;  These will only run on machines with a 287 or a 387 (and a 486 of course.)
  143. ;
  144. ;  Some of the speed gains from this code are due to the storing of the NPU
  145. ;    status word directly to the AX register.  FRACTINT will use these
  146. ;     routines only when it finds a 287 or better coprocessor installed.
  147.  
  148. .286
  149. .287
  150.  
  151. .data
  152.  
  153.     extrn new:qword, old:qword, tmp:qword
  154.     extrn rqlim:qword, magnitude:qword, tempsqrx:qword, tempsqry:qword
  155.     extrn cpu:word, fpu:word, floatparm:word
  156.  
  157. .code
  158.  
  159.     ; px,py = floatparm->x,y
  160.     ; ox,oy = oldx,oldy
  161.     ; nx,ny = newx,newy
  162.     ; nx2,ny2 = newxsquared,newysquared
  163.     ; tx,ty = tempx, tempy (used in lambda)
  164.  
  165. FManOWarfpFractal    proc uses si di
  166.                ; From Art Matrix via Lee Skinner
  167.     fld    tempsqrx        ; ox2
  168.     fsub    tempsqry        ; ox2-oy2
  169.     mov    bx,floatparm
  170.     fadd    tmp            ; ox2-oy2+tx
  171.     fadd    qword ptr [bx]        ; newx
  172.     fld    old            ; oldx newx
  173.     fmul    old+8            ; oldx*oldy newx
  174.     fadd    st,st            ; oldx*oldy*2 newx
  175.     fadd    tmp+8            ; oldx*oldy*2+tmp.y newx
  176.     fadd    qword ptr [bx+8]    ; newy newx
  177.     mov    si,offset old        ; tmp=old
  178.     mov    di,offset tmp
  179.     mov    ax,ds
  180.     mov    es,ax
  181.     mov    cx,8
  182.     rep    movsw
  183.     call    near ptr asmfloatbailout
  184.     ret
  185. FManOWarfpFractal    endp
  186.  
  187. FJuliafpFractal proc uses si di
  188.     ; Julia/Mandelbrot floating-point orbit function.
  189.     fld    tempsqrx
  190.     fsub    tempsqry
  191.     mov    bx,floatparm
  192.     fadd    qword ptr [bx]        ;/* add floatparm->x */
  193.     fld    qword ptr old        ;/* now get 2*x*y+floatparm->y */
  194.     fmul    qword ptr old+8
  195.     fadd    st,st
  196.     fadd    qword ptr [bx+8]    ; add floatparm->y
  197.     call    near ptr asmfloatbailout
  198.     ret
  199. FJuliafpFractal         endp
  200.  
  201. FBarnsley1FPFractal    proc uses si di
  202.     ; From Fractals Everywhere by Michael Barnsley
  203.     mov    bx,floatparm
  204.     fld    qword ptr [bx]        ;/* STACK: px */
  205.     fld    qword ptr [bx+8]    ;/* py px */
  206.     fld    qword ptr old        ;/* ox py px */
  207.     ftst                ;/*** we will want this later */
  208.     fstsw    ax            ;/*** 287 or better only */
  209.     fld    old+8            ;/* oy ox py px */
  210.     fld    st(1)            ;/* ox oy ox py px */
  211.     fmul    st,st(4)        ;/* ox*px oy ox py px */
  212.     fld    st(1)            ;/* oy ox*px oy ox py px */
  213.     fmul    st,st(4)        ;/* oy*py ox*px oy ox py px */
  214.     fsub                ;/* (ox*px-oy*py) oy ox py px */
  215.     fxch                ;/* oy (oxpx-oypy) ox py px */
  216.     fmul    st,st(4)        ;/* oy*px (oxpx-oypy) ox py px */
  217.     fxch    st(2)            ;/* ox (oxpx-oypy) oy*px py px */
  218.     fmul    st,st(3)        ;/* ox*py (oxpx-oypy) oy*px py px */
  219.     faddp    st(2),st        ;/* oxpx-oypy oypx+oxpy py px */
  220.     sahf                ;/*** use the saved status (finally) */
  221.     jb    BFPM1add
  222.     fsubrp    st(3),st        ;/* oypx+oxpy py nx */
  223.     fsubr                ;/* ny nx */
  224.     jmp    short BFPM1cont
  225. BFPM1add:
  226.     faddp    st(3),st        ;/* oypx+oxpy py nx */
  227.     fadd                ;/* ny nx */
  228. BFPM1cont:
  229.     call    near ptr asmfloatbailout
  230.     ret
  231. FBarnsley1FPFractal endp
  232.  
  233. FBarnsley2FPFractal proc uses si di
  234.     ; Also from Fractals Everywhere
  235.     mov    bx,floatparm
  236.     fld    qword ptr [bx]        ;/* STACK: px */
  237.     fld    qword ptr [bx+8]    ;/* py px */
  238.     fld    qword ptr old        ;/* ox py px */
  239.     fld    qword ptr old+8     ;/* oy ox py px */
  240.     fld    st(1)            ;/* ox oy ox py px */
  241.     fmul    st,st(4)        ;/* ox*px oy ox py px */
  242.     fld    st(1)            ;/* oy ox*px oy ox py px */
  243.     fmul    st,st(4)        ;/* oy*py ox*px oy ox py px */
  244.     fsub                ;/* (ox*px-oy*py) oy ox py px */
  245.     fxch    st(2)            ;/* ox oy (oxpx-oypy) py px */
  246.     fmul    st,st(3)        ;/* ox*py oy (oxpx-oypy) py px */
  247.     fxch                ;/* oy ox*py (oxpx-oypy) py px */
  248.     fmul    st,st(4)        ;/* oy*px ox*py (oxpx-oypy) py px */
  249.     fadd                ;/* oypx+oxpy oxpx-oypy py px */
  250.     ftst
  251.     fstsw    ax            ;/* 287 or better only */
  252.     sahf
  253.     jb    BFPM2add
  254.     fsubrp    st(2),st        ;/* oxpx-oypy ny px */
  255.     fsubrp    st(2),st        ;/* ny nx */
  256.     jmp    short BFPM2cont
  257. BFPM2add:
  258.     faddp    st(2),st        ;/* oxpx-oypy ny px */
  259.     faddp    st(2),st        ;/* ny nx */
  260. BFPM2cont:
  261.     call    near ptr asmfloatbailout
  262.     ret
  263. FBarnsley2FPFractal endp
  264.  
  265. FLambdaFPFractal proc uses si di
  266.     ; tempsqrx and tempsqry can be used -- the C code doesn't use them!
  267.     fld    tempsqry        ;oy2
  268.     fsub    tempsqrx        ;oy2-ox2
  269.     fld    old            ;ox oy2-ox2
  270.     fadd    st(1),st        ;ox tx=ox+oy2-ox2
  271.     fadd    st,st            ;2ox tx
  272.     fld1                ;1 2ox tx
  273.     fsubr                ;(1-2ox) tx
  274.     fmul    old+8            ;ty=oy(1-2ox) tx
  275.     fld    st(1)            ;tx ty tx -- duplicate these now
  276.     fld    st(1)            ;ty tx ty tx
  277.     mov    bx,floatparm
  278.     fld    qword ptr [bx+8]    ;py ty tx ty tx -- load y first
  279.     fld    qword ptr [bx]        ;px py ty tx ty tx
  280.     fmul    st(5),st        ;px py ty tx ty pxtx
  281.     fmulp    st(4),st        ;py ty tx pxty pxtx
  282.     fmul    st(2),st        ;py ty pytx pxty pxtx
  283.     fmul                ;pyty pytx pxty pxtx
  284.     fsubp    st(3),st        ;pytx pxty nx=pxtx-pyty
  285.     fadd                ;ny=pxty+pytx nx
  286.     call    near ptr asmfloatbailout
  287.     ret
  288. FLambdaFPFractal endp
  289.  
  290. asmfloatbailout proc near
  291.     ; called with new.y and new.x on stack and clears the stack
  292.     ; destroys SI and DI: caller must save them
  293.     fst    qword ptr new+8
  294.     fmul    st,st            ;/* ny2 nx */
  295.     fst    tempsqry
  296.     fxch                ;/* nx ny2 */
  297.     fst    qword ptr new
  298.     fmul    st,st            ;/* nx2 ny2 */
  299.     fst    tempsqrx
  300.     fadd
  301.     fst    magnitude
  302.     fcomp    rqlim            ;/*** stack is empty */
  303.     fstsw    ax            ;/*** 287 and up only */
  304.     sahf
  305.     jae    bailout
  306.     mov    si,offset new
  307.     mov    di,offset old
  308.     mov    ax,ds
  309.     mov    es,ax
  310.     mov    cx,8
  311.     rep    movsw
  312.     xor    ax,ax
  313.     ret
  314. bailout:
  315.     mov    ax,1
  316.     ret
  317. asmfloatbailout endp
  318.  
  319.  
  320. .8086
  321. .8087
  322.  
  323.     end
  324.  
  325.