home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / progmisc / frasrc18.zip / NEWTON.ASM < prev    next >
Assembly Source File  |  1992-12-19  |  6KB  |  348 lines

  1. ; NEWTON.ASM : Procedure NewtonFractal() from FRACTINT.
  2. ; Lee Daniel Crocker, 4/23/89.
  3. ;
  4. ; Tabs: 8
  5. ;
  6. ; Modifications:
  7. ;   BT = Bert Tyler
  8. ;   TW = Timothy Wegner
  9. ;   RD = Robert Day
  10. ;   MP = Mark Peterson
  11. ;
  12. ; Note: newton.asm was totally rewritten by Lee Crocker for FRACTINT 10.0
  13. ;    for integration with the newly structured fractal engine in calcmand.c
  14. ;    and fractals.c. The current routine consists of the inner orbit
  15. ;    calculation, with the supporting code removed. Early versions of
  16. ;    newton.asm contained a complete newton fractal function.
  17. ;
  18. ; Assembled by Microsoft Macro Assembler 5.1, for use with Microsoft C 5.1.
  19. ;
  20.  
  21. ; Required for compatibility if Turbo ASM (BT 5/20/89)
  22.  
  23. IFDEF ??version
  24. MASM51
  25. QUIRKS
  26. ENDIF
  27.  
  28. .model    medium, c
  29.  
  30. public    NewtonFractal2
  31. public    invertz2
  32.  
  33. .data
  34.     extrn    color:word, maxcolor:word, degree:word, basin:word
  35.     extrn    row:word, col:word
  36.  
  37.     extrn    dx0:dword, dy0:dword
  38.     extrn    dx1:dword, dy1:dword
  39.  
  40.     extrn    old:qword, new:qword, d1overd:qword, roverd:qword
  41.     extrn    threshold:qword, floatmin:qword, floatmax:qword
  42.     extrn    f_radius:qword, f_xcenter:qword, f_ycenter:qword
  43.     extrn    roots:word, tempsqrx:qword
  44.  
  45. statw    dw    ?
  46.  
  47. .code
  48.  
  49. public    NewtonFractal2
  50. NewtonFractal2 proc
  51.  
  52. ;
  53. ; cpower(&old, degree-1, &tmp)
  54. ;
  55.     mov    ax, degree
  56.     dec    ax
  57.  
  58.     fld    old + 8
  59.     fld    old
  60. ;
  61. ; cpower() is expanded inline here.
  62. ;
  63.     shr    ax, 1
  64.     jnc    load1            ; if (exp & 1)
  65.  
  66.     fld    st(1)
  67.     fld    st(1)
  68.     jmp    short looptop        ; tmp = old
  69. load1:
  70.     fldz
  71.     fld1                ; else tmp = [1,0]
  72. looptop:
  73.     cmp    ax, 0
  74.     je    loopexit        ; while (exp)
  75.  
  76.     fld    st(2)            ; RD 5/7/89: Calculate xt^2 - yt^2
  77.     fadd    st, st(4)        ; by using (xt+yt)*(xt-yt), which
  78.     fld    st(3)            ; trades one multiplication for an
  79.     fsub    st, st(5)        ; addition.  This trick saves a
  80.     fmul                ; whopping 1.2% of time.
  81.  
  82.     fld    st(4)
  83.     fmul    st, st(4)
  84.     fadd    st, st            ; yt = 2 * xt * yt
  85.  
  86.     fstp    st(5)            ; tmp.y = yt
  87.     fstp    st(3)            ; tmp.x = xt
  88.  
  89.     shr    ax, 1
  90.     jnc    looptop         ; if (exp & 1)
  91.  
  92.     fld    st(2)
  93.     fmul    st, st(1)
  94.     fld    st(4)
  95.     fmul    st, st(3)
  96.     fsub                ; tmp.x = xt * tmp.x - yt * tmp.y
  97.  
  98.     fld    st(3)
  99.     fmul    st, st(3)
  100.     fld    st(5)
  101.     fmul    st, st(3)
  102.     fadd                ; tmp.y = xt * tmp.y + yt * tmp.x
  103.     fstp    st(3)
  104.     fstp    st(1)
  105.  
  106.     jmp    short looptop
  107. loopexit:
  108.     fstp    st(2)
  109.     fstp    st(2)
  110. ;
  111. ; End of complex_power() routine.  Result is in ST, ST(1)
  112. ;
  113. ;
  114. ; complex_mult(tmp, old, &new);
  115. ;
  116.     fld    old + 8
  117.     fld    old
  118.  
  119.     fld    st(3)        ; tmp.y
  120.     fmul    st, st(1)   ; old.x
  121.     fld    st(3)        ; tmp.x
  122.     fmul    st, st(3)   ; old.y
  123.     fadd
  124.     fld    st(3)        ; tmp.x
  125.     fmul    st, st(2)   ; old.x
  126.     fld    st(5)        ; tmp.y
  127.     fmul    st, st(4)   ; old.y
  128.     fsub
  129. ;
  130. ; if (DIST1(new) < THRESHOLD) {
  131. ;
  132.     fld1
  133.     fsubr    st, st(1)
  134.     fmul    st, st
  135.     fld    st(2)        ; new.y
  136.     fmul    st, st
  137.     fadd
  138.     fcomp    threshold
  139.     fstsw    statw
  140.     mov    ax, statw
  141.     sahf
  142.     jnc    notless
  143. ;
  144. ; if (fractype == NEWTBASIN) {
  145. ;
  146.     mov    ax, basin
  147.     cmp    ax, 0
  148.     je    notbasin
  149.  
  150.     mov    bx, roots
  151.     mov    dx, -1            ; tempcolor = -1
  152.     sub    cx, cx
  153. dloop:
  154.     fld    qword ptr [bx]    ; roots[i].x
  155.     fsub    st, st(3)    ; old.x
  156.     fmul    st, st
  157.     fld    qword ptr [bx+8]; roots[i].y
  158.     fsub    st, st(5)    ; old.y
  159.     fmul    st, st
  160.     fadd
  161.     fcomp    threshold
  162.     fstsw    statw
  163.     mov    ax, statw
  164.     sahf                ; if (distance(roots[i],old) < threshold)...
  165.     jnc    nl2
  166.  
  167. ; TW commented out next few lines and add dx,ax to eliminate newtbasin
  168. ; color shades per Phil Wilson's request 12/03/89
  169.  
  170. ; TW put it back in in response to another use as an option! 7/7/90
  171.     mov    dx, cx
  172.     cmp    basin,2            ; basin==2 is flag for stripes
  173.     jne    nostripes
  174.     mov    ax, color
  175.     and    ax, 1
  176.     shl    ax, 1
  177.     shl    ax, 1
  178.     shl    ax, 1
  179.  
  180.     and    dx, 7
  181.     add    dx, ax
  182. nostripes:
  183.     inc    dx            ; tempcolor = 1+(i&7)+((color&1)<<3)
  184.     jmp    short nfb        ; break
  185. nl2:
  186.     add    bx, 16
  187.     inc    cx
  188.     cmp    cx, degree
  189.     jl    dloop
  190. nfb:
  191.     mov    ax, dx
  192.     cmp    dx, -1
  193.     jne    notm1
  194.     mov    ax, maxcolor        ; if (tmpcolor == -1)...
  195. notm1:
  196.     mov    color, ax
  197. notbasin:
  198.     mov    ax, 1
  199.     jmp    nlexit
  200. notless:
  201.     fld    d1overd
  202.     fmul    st(2), st        ; new.y *= d1overd
  203.     fmul
  204.     fld    roverd
  205.     fadd                ; new.x = d1overd * new.x + roverd
  206.  
  207.     fld    st(5)        ; tmp.y
  208.     fmul    st, st
  209.     fld    st(5)        ; tmp.x
  210.     fmul    st, st
  211.     fadd
  212.     fcom    floatmin
  213.     fstsw    statw
  214.     mov    ax, statw
  215.     sahf                ; if (mod(tmp) < FLT_MIN) {
  216.     jnc    cont
  217.     mov    ax, 1
  218.     fstp    st
  219.     jmp    nlexit
  220. cont:
  221.     fld1
  222.     fdivr
  223.     fst    st(4)        ; old.y
  224.     fstp    st(3)        ; old.x
  225.  
  226.     fld    st(4)        ; tmp.x
  227.     fmul    st, st(1)   ; new.x
  228.     fld    st(6)        ; tmp.y
  229.     fmul    st, st(3)   ; new.y
  230.     fadd
  231.     fmulp    st(3), st   ; old.x
  232.  
  233.     fld    st(4)        ; tmp.x
  234.     fmul    st, st(2)   ; new.y
  235.     fld    st(6)        ; tmp.y
  236.     fmul    st, st(2)   ; new.x
  237.     fsub
  238.     fmulp    st(4), st   ; old.y    ; old = new / tmp
  239.  
  240. ; MP Orbit Bug Fix 11/1/90
  241. ;    fstp    new
  242. ;    fstp    new + 8
  243. ;    fstp    old
  244. ;    fstp    old + 8
  245.     fstp    st
  246.     fstp    st
  247.     fst    new
  248.     fstp    old
  249.     fst    new + 8
  250.     fstp    old + 8
  251.  
  252.     mov    ax, 0
  253.     jmp    nlx2
  254.  
  255. nlexit:
  256.  
  257. ;MP Orbit Bug Fix 11/1/90
  258. ;    fstp    new
  259. ;    fstp    new + 8
  260.     fstp    st
  261.     fstp    st
  262.     fstp    new
  263.     fstp    new + 8
  264.  
  265. nlx2:
  266.     fstp    st
  267.     fstp    st
  268.  
  269.     ret
  270. NewtonFractal2 endp
  271. ;
  272. ;
  273. ;
  274. public    invertz2
  275. invertz2 proc    uses si, zval:word    ; TW 11/03/89 changed zval to near
  276.  
  277.     fld    f_xcenter
  278.     fld    f_ycenter
  279.  
  280.     mov    bx, col
  281.     shl    bx, 1
  282.     shl    bx, 1
  283.     shl    bx, 1
  284.  
  285.     mov    cx, row
  286.     shl    cx, 1
  287.     shl    cx, 1
  288.     shl    cx, 1
  289.  
  290.     mov    ax, ds
  291.     lds    si, dx0
  292.     add    si, bx
  293.     fld    qword ptr [si]
  294.     mov    ds, ax
  295.     lds    si, dx1
  296.     add    si, cx
  297.     fld    qword ptr [si]
  298.     fadd
  299.     fsub    st, st(2)
  300.  
  301.     mov    ds, ax
  302.     lds    si, dy0
  303.     add    si, cx
  304.     fld    qword ptr [si]
  305.     mov    ds, ax
  306.     lds    si, dy1
  307.     add    si, bx
  308.     fld    qword ptr [si]
  309.     fadd
  310.     fsub    st, st(2)
  311.  
  312.     mov    ds, ax
  313.     fld    st(1)
  314.     fmul    st, st
  315.     fld    st(1)
  316.     fmul    st, st
  317.     fadd
  318.  
  319.     fcom    floatmin
  320.     fstsw    statw
  321.     mov    ax, statw
  322.     sahf
  323.     jnc    inl1
  324.  
  325.     fstp    st
  326.     fld    floatmax
  327.     jmp    icom
  328. inl1:
  329.     fld    f_radius
  330.     fdivr
  331. icom:
  332.     fst    tempsqrx
  333.  
  334.     fmul    st(2), st
  335.     fmul
  336.     faddp    st(2), st
  337.     faddp    st(2), st
  338.  
  339. ;    lds    si, zval    ; TW 11/03/89 zval is now a near pointer
  340.     mov    si, zval    ; TW
  341.     fstp    qword ptr [si+8]
  342.     fstp    qword ptr [si]
  343.  
  344.     ret
  345. invertz2 endp
  346.  
  347. END
  348.