File: dos\newton.asm

    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 6.1, for use with Microsoft C 7.0.
   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   coloriter:dword, 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         extrn   delxx:tbyte, delxx2:tbyte
   45         extrn   delyy:tbyte, delyy2:tbyte
   46         extrn   xxmin:qword, yymax:qword
   47         extrn   use_grid:word
   48 statw   dw      ?
   49 
   50 .code
   51 
   52 public  NewtonFractal2
   53 NewtonFractal2 proc
   54 
   55 ;
   56 ; cpower(&old, degree-1, &tmp)
   57 ;
   58         mov     ax, degree
   59         dec     ax
   60 
   61         fld     old + 8
   62         fld     old
   63 ;
   64 ; cpower() is expanded inline here.
   65 ;
   66         shr     ax, 1
   67         jnc     load1                   ; if (exp & 1)
   68 
   69         fld     st(1)
   70         fld     st(1)
   71         jmp     short looptop           ; tmp = old
   72 load1:
   73         fldz
   74         fld1                            ; else tmp = [1,0]
   75 looptop:
   76         cmp     ax, 0
   77         je      loopexit                ; while (exp)
   78 
   79         fld     st(2)                   ; RD 5/7/89: Calculate xt^2 - yt^2
   80         fadd    st, st(4)               ; by using (xt+yt)*(xt-yt), which
   81         fld     st(3)                   ; trades one multiplication for an
   82         fsub    st, st(5)               ; addition.  This trick saves a
   83         fmul                            ; whopping 1.2 of time.
   84 
   85         fld     st(4)
   86         fmul    st, st(4)
   87         fadd    st, st                  ; yt = 2 * xt * yt
   88 
   89         fstp    st(5)                   ; tmp.y = yt
   90         fstp    st(3)                   ; tmp.x = xt
   91 
   92         shr     ax, 1
   93         jnc     looptop                 ; if (exp & 1)
   94 
   95         fld     st(2)
   96         fmul    st, st(1)
   97         fld     st(4)
   98         fmul    st, st(3)
   99         fsub                            ; tmp.x = xt * tmp.x - yt * tmp.y
  100 
  101         fld     st(3)
  102         fmul    st, st(3)
  103         fld     st(5)
  104         fmul    st, st(3)
  105         fadd                            ; tmp.y = xt * tmp.y + yt * tmp.x
  106         fstp    st(3)
  107         fstp    st(1)
  108 
  109         jmp     short looptop
  110 loopexit:
  111         fstp    st(2)
  112         fstp    st(2)
  113 ;
  114 ; End of complex_power() routine.  Result is in ST, ST(1)
  115 ;
  116 ;
  117 ; complex_mult(tmp, old, &new);
  118 ;
  119         fld     old + 8
  120         fld     old
  121 
  122         fld     st(3)       ; tmp.y
  123         fmul    st, st(1)   ; old.x
  124         fld     st(3)       ; tmp.x
  125         fmul    st, st(3)   ; old.y
  126         fadd
  127         fld     st(3)       ; tmp.x
  128         fmul    st, st(2)   ; old.x
  129         fld     st(5)       ; tmp.y
  130         fmul    st, st(4)   ; old.y
  131         fsub
  132 ;
  133 ; if (DIST1(new) < THRESHOLD) {
  134 ;
  135         fld1
  136         fsubr   st, st(1)
  137         fmul    st, st
  138         fld     st(2)       ; new.y
  139         fmul    st, st
  140         fadd
  141         fcomp   threshold
  142         fstsw   statw
  143         mov     ax, statw
  144         sahf
  145         jnc     notless
  146 ;
  147 ; if (fractype == NEWTBASIN) {
  148 ;
  149         mov     ax, basin
  150         cmp     ax, 0
  151         je      notbasin
  152 
  153         mov     bx, roots
  154         mov     dx, -1                  ; tempcolor = -1
  155         sub     cx, cx
  156 dloop:
  157         fld     qword ptr [bx]  ; roots[i].x
  158         fsub    st, st(3)       ; old.x
  159         fmul    st, st
  160         fld     qword ptr [bx+8]; roots[i].y
  161         fsub    st, st(5)       ; old.y
  162         fmul    st, st
  163         fadd
  164         fcomp   threshold
  165         fstsw   statw
  166         mov     ax, statw
  167         sahf                            ; if (distance(roots[i],old) < threshold)...
  168         jnc     nl2
  169 
  170 ; TW commented out next few lines and add dx,ax to eliminate newtbasin
  171 ; color shades per Phil Wilson's request 12/03/89

; TW put it back in in response to another use as an option! 7/7/90
        mov     dx, cx
        cmp     basin,2                 ; basin==2 is flag for stripes
        jne     nostripes
        mov     ax, word ptr coloriter
        and     ax, 1
        shl     ax, 1
        shl     ax, 1
        shl     ax, 1

        and     dx, 7
        add     dx, ax
nostripes:
        inc     dx                      ; tempcolor = 1+(i&7)+((color&1)<<3)
        jmp     short nfb               ; break
nl2:
        add     bx, 16
        inc     cx
        cmp     cx, degree
        jl      dloop
nfb:
        mov     ax, dx
        cmp     dx, -1
        jne     notm1
        mov     ax, maxcolor            ; if (tmpcolor == -1)...
notm1:
        mov     word ptr coloriter, ax
        mov     word ptr coloriter+2, 0
notbasin:
        mov     ax, 1
        jmp     nlexit
notless:
        fld     d1overd
        fmul    st(2), st               ; new.y *= d1overd
        fmul
        fld     roverd
        fadd                            ; new.x = d1overd * new.x + roverd

        fld     st(5)       ; tmp.y
        fmul    st, st
        fld     st(5)       ; tmp.x
        fmul    st, st
        fadd
        fcom    floatmin
        fstsw   statw
        mov     ax, statw
        sahf                            ; if (mod(tmp) < FLT_MIN) {
        jnc     cont
        mov     ax, 1
        fstp    st
        jmp     nlexit
cont:
        fld1
        fdivr
        fst     st(4)       ; old.y
        fstp    st(3)       ; old.x

        fld     st(4)       ; tmp.x
        fmul    st, st(1)   ; new.x
        fld     st(6)       ; tmp.y
        fmul    st, st(3)   ; new.y
        fadd
        fmulp   st(3), st   ; old.x

        fld     st(4)       ; tmp.x
        fmul    st, st(2)   ; new.y
        fld     st(6)       ; tmp.y
        fmul    st, st(2)   ; new.x
        fsub
        fmulp   st(4), st   ; old.y     ; old = new / tmp

; MP Orbit Bug Fix 11/1/90
;       fstp    new
;       fstp    new + 8
;       fstp    old
;       fstp    old + 8
        fstp    st
        fstp    st
        fst     new
        fstp    old
        fst     new + 8
        fstp    old + 8

        mov     ax, 0
        jmp     nlx2

nlexit:

;MP Orbit Bug Fix 11/1/90
;       fstp    new
;       fstp    new + 8
        fstp    st
        fstp    st
        fstp    new
        fstp    new + 8

nlx2:
        fstp    st
        fstp    st

        ret
NewtonFractal2 endp
;
;
;
; TW added support for no grid version - does not use dx0/dx1 pixel
;    grid id use_grid == 0.

public  invertz2
invertz2 proc   uses si, zval:word

        fld     f_xcenter   ;   xcent
        fld     f_ycenter   ;   ycent xcent
        mov     ax, ds

        cmp     use_grid,0  ; inversion support added
        je      skip_grid   ; don't use dx0 grid
  172 
  173         mov     bx, col     ; use dx0 grid
  174         shl     bx, 1
  175         shl     bx, 1
  176         shl     bx, 1
  177 
  178         mov     cx, row
  179         shl     cx, 1
  180         shl     cx, 1
  181         shl     cx, 1
  182 
  183         lds     si, dx0
  184         add     si, bx
  185         fld     qword ptr [si]   ; dx0[col]  ycent xcent
  186         mov     ds, ax
  187         lds     si, dx1
  188         add     si, cx
  189         fld     qword ptr [si] ; dx1[row] dx0[col]       ycent xcent
  190         fadd                   ; dx1[row]+dx0[col]       ycent xcent
  191         fsub    st, st(2)      ; dx1[row]+dx0[col]-xcent ycent xcent
  192 
  193         mov     ds, ax
  194         lds     si, dy0
  195         add     si, cx
  196         fld     qword ptr [si]  ; dy0[row]                dx1[row]+dx0[col]-xcent ycent xcent
  197         mov     ds, ax
  198         lds     si, dy1
  199         add     si, bx
  200         fld     qword ptr [si]  ; dy1[col] dy0[row]       dx1[row]+dx0[col]-xcent ycent xcent
  201         fadd                    ; dy1[col]+dy0[row]       dx1[row]+dx0[col]-xcent ycent xcent
  202         fsub    st, st(2)       ; dy1[col]+dy0[row]-ycent dx1[row]+dx0[col]-xcent ycent xcent
  203 
  204         jmp          after_load
  205 skip_grid:
  206         fild    word ptr row     ; row ycent xcent
  207         fld     tbyte ptr delxx2 ; delxx2 row ycent xcent
  208         fmulp   st(1),st(0)      ; delxx2*row ycent xcent
  209         fild    word ptr col     ; col delxx2*row ycent xcent
  210         fld     tbyte ptr delxx  ; delxx col delxx2*row  ycent xcent
  211         fmulp   st(1),st(0)      ; delxx*col delxx2*row  ycent xcent
  212         faddp   st(1),st(0)      ; delxx*col+delxx2*row  ycent xcent
  213         fadd    qword ptr xxmin  ; xxmin+delxx*col+delxx2*row ycent xcent       
  214         fsub    st, st(2) ; xxmin+col*delxx+row*delxx2-xcent ycent xcent
  215   
  216         fild    word ptr row
  217         fld     tbyte ptr delyy
  218         fmulp   st(1),st(0)
  219         fsubr   qword ptr yymax
  220         fild    word ptr col
  221         fld     tbyte ptr delyy2
  222         fmulp   st(1),st(0)
  223         fsubp   st(1),st(0)
  224         fsub    st, st(2)
  225 after_load:
  226 
  227         mov     ds, ax 
  228         fld     st(1)    
  229         fmul    st, st   
  230         fld     st(1)    
  231         fmul    st, st   
  232         fadd             
  233 
  234         fcom    floatmin
  235         fstsw   statw
  236         mov     ax, statw
  237         sahf
  238         jnc     inl1
  239 
  240         fstp    st
  241         fld     floatmax
  242         jmp     icom
  243 inl1:
  244         fld     f_radius
  245         fdivr
  246 icom:
  247         fst     tempsqrx
  248 
  249         fmul    st(2), st
  250         fmul
  251         faddp   st(2), st
  252         faddp   st(2), st
  253 
  254         mov     si, zval
  255         fstp    qword ptr [si+8]
  256         fstp    qword ptr [si]
  257 
  258         ret
  259 invertz2 endp
  260 
  261 END
  262