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