File: dos\fracsuba.asm

    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
        extrn   multiply:far            ; this routine is in 'general.asm'

        extrn   floatbailout:word               ; this routine is in 'fractals.c'

.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 FRACTALS_TEXT

;; Note: the check for overflow is now in StandardFractal(), JCO 2/12/95

asmlMODbailout  proc near
;
; 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           ; This test and next one are extraneous:
;       mov     ax,WORD PTR lnew                ; take    x > llimit2  and sqr both sides
;       mov     dx,WORD PTR lnew+2      ;       x^2 > llimit
;       or      dx,dx                           ; if    x^2 > llimit then surely
;       jge     lnewx                           ; x^2 + y^2 > llimit
;       neg     ax                              ; which was just checked!
;       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
asmlMODbailout  endp

asmlREALbailout proc near
;
; equivalent to the C code:
;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
;  if (ltempsqrx >= llimit || overflow)
;              { overflow=0; return(1); }
;  lold = lnew;
;  return(0);
;
;  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
        mov     WORD PTR ltempsqry,ax
        mov     WORD PTR ltempsqry+2,dx
;  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
        add     sp,20
        mov     WORD PTR ltempsqrx,ax
        mov     WORD PTR ltempsqrx+2,dx
;  lmagnitud = ltempsqrx + ltempsqry;
        add     ax,WORD PTR ltempsqry
        adc     dx,WORD PTR ltempsqry+2
        mov     WORD PTR lmagnitud,ax
        mov     WORD PTR lmagnitud+2,dx
        mov     ax,WORD PTR ltempsqrx   ; restore ltempsqrx to ax & dx
        mov     dx,WORD PTR ltempsqrx+2
;  if (ltempsqrx >= llimit
        cmp     dx,WORD PTR llimit+2
        jl      chkoflow
        jg      bailout
        cmp     ax,WORD PTR llimit
        jae     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
asmlREALbailout endp

asmlIMAGbailout proc near
;
; equivalent to the C code:
;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
;  if (ltempsqry >= llimit || 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
        mov     ax,WORD PTR ltempsqry   ; restore ltempsqry to ax & dx
        mov     dx,WORD PTR ltempsqry+2
;  if (ltempsqry >= llimit
        cmp     dx,WORD PTR llimit+2
        jl      chkoflow
        jg      bailout
        cmp     ax,WORD PTR llimit
        jae     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
asmlIMAGbailout endp

asmlORbailout   proc near
;
; equivalent to the C code:
;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
;  if (ltempsqrx >= llimit || ltempsqry >= llimit || 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
        mov     ax,WORD PTR ltempsqry   ; restore ltempsqry to ax & dx
        mov     dx,WORD PTR ltempsqry+2
;  if (ltempsqry >= llimit
        cmp     dx,WORD PTR llimit+2
        jl      chkxnxt
        jg      bailout
        cmp     ax,WORD PTR llimit
        jae     bailout
;   || ltempsqrx >= llimit
chkxnxt:
        mov     ax,WORD PTR ltempsqrx
        mov     dx,WORD PTR ltempsqrx+2
        cmp     dx,WORD PTR llimit+2
        jl      chkoflow
        jg      bailout
        cmp     ax,WORD PTR llimit
        jae     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
asmlORbailout   endp

asmlANDbailout  proc near
;
; equivalent to the C code:
;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
;  if ((ltempsqrx >= llimit && ltempsqry >= llimit) || 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
        mov     ax,WORD PTR ltempsqry   ; restore ltempsqry to ax & dx
        mov     dx,WORD PTR ltempsqry+2
;  if ((ltempsqry >= llimit
        cmp     dx,WORD PTR llimit+2
        jl      chkoflow
        jg      chkx
        cmp     ax,WORD PTR llimit
        jae     chkx
        jmp     short chkoflow
;  && ltempsqrx >= llimit)
chkx:   mov     ax,WORD PTR ltempsqrx
        mov     dx,WORD PTR ltempsqrx+2
        cmp     dx,WORD PTR llimit+2
        jl      chkoflow
        jg      bailout
        cmp     ax,WORD PTR llimit
        jae     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
asmlANDbailout  endp

asmlMANHbailout proc near
;
; equivalent to the C code:
;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
;  magnitude = fabs(new.x) + fabs(new.y);
;  if(magnitude * magnitude) >= rqlim) 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
;  lold = abs(new.x) + abs(new.y)       ; use lold as temp storage
        mov     ax,WORD PTR lnew
        mov     dx,WORD PTR lnew+2
        cmp     dx,0
        jge     xpos    ; if negative, negate + 1
        not     ax
        not     dx
        add     ax,1
        adc     dx,0
xpos:   mov     bx,WORD PTR lnew+4
        mov     cx,WORD PTR lnew+6
        cmp     cx,0
        jge     ypos    ; if negative, negate + 1
        not     bx
        not     cx
        add     bx,1
        adc     cx,0
ypos:   add     ax,bx
        adc     dx,cx
        jge     oksum
        mov     overflow,1
        jmp     short bailout
oksum:  mov     WORD PTR lold,ax
        mov     WORD PTR lold+2,dx
;  lold * lold;
        push    bitshift
        push    WORD PTR lold+2
        push    WORD PTR lold
        push    WORD PTR lold+2
        push    WORD PTR lold
        call    FAR PTR multiply
        add     sp,10
;  if ((lold * lold) >= llimit
        cmp     dx,WORD PTR llimit+2
        jl      chkoflow
        jg      bailout
        cmp     ax,WORD PTR llimit
        jae     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
asmlMANHbailout endp

asmlMANRbailout proc near
;
; equivalent to the C code:
;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
;  magnitude = fabs(new.x + new.y);
;  if(magnitude * magnitude) >= rqlim) 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
;  lold = abs(new.x + new.y)    ; lold used as temp storage
        mov     ax,WORD PTR lnew
        mov     dx,WORD PTR lnew+2
        add     ax,WORD PTR lnew+4
        adc     dx,WORD PTR lnew+6      ; square next, don't need abs
   15         mov     WORD PTR lold,ax
   16         mov     WORD PTR lold+2,dx
   17 ;  lmagnitud * lmagnitud;
   18         push    bitshift
   19         push    WORD PTR lold+2
   20         push    WORD PTR lold
   21         push    WORD PTR lold+2
   22         push    WORD PTR lold
   23         call    FAR PTR multiply
   24         add     sp,10
   25 ;  if ((lold * lold) >= llimit
   26         cmp     dx,WORD PTR llimit+2
   27         jl      chkoflow
   28         jg      bailout
   29         cmp     ax,WORD PTR llimit
   30         jae     bailout
   31 ;   || overflow)
   32 chkoflow:
   33 ;       cmp     overflow,0
   34 ;       jne     bailout
   35 ;  else {
   36 ;  lold = lnew;
   37         mov     ax,WORD PTR lnew
   38         mov     dx,WORD PTR lnew+2
   39         mov     WORD PTR lold,ax
   40         mov     WORD PTR lold+2,dx
   41         mov     ax,WORD PTR lnew+4
   42         mov     dx,WORD PTR lnew+6
   43         mov     WORD PTR lold+4,ax
   44         mov     WORD PTR lold+6,dx
   45 ;  return(0); }
   46         sub     ax,ax
   47         ret
   48 bailout:
   49 ;  { overflow=0; return(1); }
   50 ;       mov     overflow,0
   51         mov     ax,1
   52         ret
   53 asmlMANRbailout endp
   54 
   55 
   56 .386
   57 
   58 asm386lMODbailout       proc near
   59 ;
   60 ; equivalent to the C code:
   61 ;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
   62 ;  lmagnitud = ltempsqrx + ltempsqry;
   63 ;  if (lmagnitud >= llimit || lmagnitud < 0 || labs(lnew.x) > llimit2
   64 ;        || labs(lnew.y) > llimit2 || overflow)
   65 ;              { overflow=0; return(1); }
   66 ;  lold = lnew;
   67 ;  return(0);
   68 ;
   69 ;  ltempsqrx = lsqr(lnew.x);
   70         push    bitshift
   71         push    DWORD PTR lnew
   72         push    DWORD PTR lnew
   73         call    FAR PTR multiply
   74         mov     WORD PTR ltempsqrx,ax
   75         mov     WORD PTR ltempsqrx+2,dx
   76 ;  ltempsqry = lsqr(lnew.y);
   77         push    bitshift
   78         push    DWORD PTR lnew+4
   79         push    DWORD PTR lnew+4
   80         call    FAR PTR multiply
   81         add     sp,20
   82         mov     WORD PTR ltempsqry,ax
   83         mov     WORD PTR ltempsqry+2,dx
   84 ;  lmagnitud = ltempsqrx + ltempsqry;
   85         mov     eax,DWORD PTR ltempsqry
   86         add     eax,DWORD PTR ltempsqrx
   87         mov     DWORD PTR lmagnitud,eax
   88 ;  if (lmagnitud >= llimit
   89         cmp     eax,DWORD PTR llimit
   90         jae     bailout
   91 ;   || overflow)
   92 chkoflow:
   93 ;       cmp     overflow,0
   94 ;       jne     bailout
   95 ;  else {
   96 ;  lold = lnew;
   97         mov     eax,DWORD PTR lnew
   98         mov     DWORD PTR lold,eax
   99         mov     eax,DWORD PTR lnew+4
  100         mov     DWORD PTR lold+4,eax
  101 ;  return(0); }
  102         sub     ax,ax
  103         ret
  104 bailout:
  105 ;  { overflow=0; return(1); }
  106 ;       mov     overflow,0
  107         mov     ax,1
  108         ret
  109 asm386lMODbailout       endp
  110 
  111 asm386lREALbailout      proc near
  112 ;
  113 ; equivalent to the C code:
  114 ;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
  115 ;  if (ltempsqrx >= llimit || overflow)
  116 ;              { overflow=0; return(1); }
  117 ;  lold = lnew;
  118 ;  return(0);
  119 ;
  120 ;  ltempsqry = lsqr(lnew.y);
  121         push    bitshift
  122         push    DWORD PTR lnew+4
  123         push    DWORD PTR lnew+4
  124         call    FAR PTR multiply
  125         mov     WORD PTR ltempsqry,ax
  126         mov     WORD PTR ltempsqry+2,dx
  127 ;  ltempsqrx = lsqr(lnew.x);
  128         push    bitshift
  129         push    DWORD PTR lnew
  130         push    DWORD PTR lnew
  131         call    FAR PTR multiply
  132         add     sp,20
  133         mov     WORD PTR ltempsqrx,ax
  134         mov     WORD PTR ltempsqrx+2,dx
  135 ;  lmagnitud = ltempsqrx + ltempsqry;
  136         mov     eax,DWORD PTR ltempsqry
  137         add     eax,DWORD PTR ltempsqrx
  138         mov     DWORD PTR lmagnitud,eax
  139 ;  if (ltempsqrx >= llimit
  140         mov     eax,DWORD PTR ltempsqrx
  141         cmp     eax,DWORD PTR llimit
  142         jae     bailout
  143 ;   || overflow)
  144 chkoflow:
  145 ;       cmp     overflow,0
  146 ;       jne     bailout
  147 ;  else {
  148 ;  lold = lnew;
  149         mov     eax,DWORD PTR lnew
  150         mov     DWORD PTR lold,eax
  151         mov     eax,DWORD PTR lnew+4
  152         mov     DWORD PTR lold+4,eax
  153 ;  return(0); }
  154         sub     ax,ax
  155         ret
  156 bailout:
  157 ;  { overflow=0; return(1); }
  158 ;       mov     overflow,0
  159         mov     ax,1
  160         ret
  161 asm386lREALbailout      endp
  162 
  163 asm386lIMAGbailout      proc near
  164 ;
  165 ; equivalent to the C code:
  166 ;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
  167 ;  if (ltempsqry >= llimit || overflow)
  168 ;              { overflow=0; return(1); }
  169 ;  lold = lnew;
  170 ;  return(0);
  171 ;
  172 ;  ltempsqrx = lsqr(lnew.x);
  173         push    bitshift
  174         push    DWORD PTR lnew
  175         push    DWORD PTR lnew
  176         call    FAR PTR multiply
  177         mov     WORD PTR ltempsqrx,ax
  178         mov     WORD PTR ltempsqrx+2,dx
  179 ;  ltempsqry = lsqr(lnew.y);
  180         push    bitshift
  181         push    DWORD PTR lnew+4
  182         push    DWORD PTR lnew+4
  183         call    FAR PTR multiply
  184         add     sp,20
  185         mov     WORD PTR ltempsqry,ax
  186         mov     WORD PTR ltempsqry+2,dx
  187 ;  lmagnitud = ltempsqrx + ltempsqry;
  188         mov     eax,DWORD PTR ltempsqry
  189         add     eax,DWORD PTR ltempsqrx
  190         mov     DWORD PTR lmagnitud,eax
  191 ;  if (ltempsqry >= llimit
  192         mov     eax,DWORD PTR ltempsqry
  193         cmp     eax,DWORD PTR llimit
  194         jae     bailout
  195 ;   || overflow)
  196 chkoflow:
  197 ;       cmp     overflow,0
  198 ;       jne     bailout
  199 ;  else {
  200 ;  lold = lnew;
  201         mov     eax,DWORD PTR lnew
  202         mov     DWORD PTR lold,eax
  203         mov     eax,DWORD PTR lnew+4
  204         mov     DWORD PTR lold+4,eax
  205 ;  return(0); }
  206         sub     ax,ax
  207         ret
  208 bailout:
  209 ;  { overflow=0; return(1); }
  210 ;       mov     overflow,0
  211         mov     ax,1
  212         ret
  213 asm386lIMAGbailout      endp
  214 
  215 asm386lORbailout        proc near
  216 ;
  217 ; equivalent to the C code:
  218 ;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
  219 ;  if (ltempsqrx >= llimit || ltempsqry >= llimit || overflow)
  220 ;              { overflow=0; return(1); }
  221 ;  lold = lnew;
  222 ;  return(0);
  223 ;
  224 ;  ltempsqrx = lsqr(lnew.x);
  225         push    bitshift
  226         push    DWORD PTR lnew
  227         push    DWORD PTR lnew
  228         call    FAR PTR multiply
  229         mov     WORD PTR ltempsqrx,ax
  230         mov     WORD PTR ltempsqrx+2,dx
  231 ;  ltempsqry = lsqr(lnew.y);
  232         push    bitshift
  233         push    DWORD PTR lnew+4
  234         push    DWORD PTR lnew+4
  235         call    FAR PTR multiply
  236         add     sp,20
  237         mov     WORD PTR ltempsqry,ax
  238         mov     WORD PTR ltempsqry+2,dx
  239 ;  lmagnitud = ltempsqrx + ltempsqry;
  240         mov     eax,DWORD PTR ltempsqry
  241         add     eax,DWORD PTR ltempsqrx
  242         mov     DWORD PTR lmagnitud,eax
  243 ;  if (ltempsqry >= llimit
  244         mov     eax,DWORD PTR ltempsqry
  245         cmp     eax,DWORD PTR llimit
  246         jae     bailout
  247 ;   || ltempsqrx >= llimit
  248 chkxnxt:
  249         mov     eax,DWORD PTR ltempsqrx
  250         cmp     eax,DWORD PTR llimit
  251         jae     bailout
  252 ;   || overflow)
  253 chkoflow:
  254 ;       cmp     overflow,0
  255 ;       jne     bailout
  256 ;  else {
  257 ;  lold = lnew;
  258         mov     eax,DWORD PTR lnew
  259         mov     DWORD PTR lold,eax
  260         mov     eax,DWORD PTR lnew+4
  261         mov     DWORD PTR lold+4,eax
  262 ;  return(0); }
  263         sub     ax,ax
  264         ret
  265 bailout:
  266 ;  { overflow=0; return(1); }
  267 ;       mov     overflow,0
  268         mov     ax,1
  269         ret
  270 asm386lORbailout        endp
  271 
  272 asm386lANDbailout       proc near
  273 ;
  274 ; equivalent to the C code:
  275 ;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
  276 ;  if ((ltempsqrx >= llimit && ltempsqry >= llimit) || overflow)
  277 ;              { overflow=0; return(1); }
  278 ;  lold = lnew;
  279 ;  return(0);
  280 ;
  281 ;  ltempsqrx = lsqr(lnew.x);
  282         push    bitshift
  283         push    DWORD PTR lnew
  284         push    DWORD PTR lnew
  285         call    FAR PTR multiply
  286         mov     WORD PTR ltempsqrx,ax
  287         mov     WORD PTR ltempsqrx+2,dx
  288 ;  ltempsqry = lsqr(lnew.y);
  289         push    bitshift
  290         push    DWORD PTR lnew+4
  291         push    DWORD PTR lnew+4
  292         call    FAR PTR multiply
  293         add     sp,20
  294         mov     WORD PTR ltempsqry,ax
  295         mov     WORD PTR ltempsqry+2,dx
  296 ;  lmagnitud = ltempsqrx + ltempsqry;
  297         mov     eax,DWORD PTR ltempsqry
  298         add     eax,DWORD PTR ltempsqrx
  299         mov     DWORD PTR lmagnitud,eax
  300 ;  if ((ltempsqry >= llimit
  301         mov     eax,DWORD PTR ltempsqry
  302         cmp     eax,DWORD PTR llimit
  303         jl      chkoflow
  304 ;  && ltempsqrx >= llimit)
  305 chkx:   mov     eax,DWORD PTR ltempsqrx
  306         cmp     eax,DWORD PTR llimit
  307         jae     bailout
  308 ;   || overflow)
  309 chkoflow:
  310 ;       cmp     overflow,0
  311 ;       jne     bailout
  312 ;  else {
  313 ;  lold = lnew;
  314         mov     eax,DWORD PTR lnew
  315         mov     DWORD PTR lold,eax
  316         mov     eax,DWORD PTR lnew+4
  317         mov     DWORD PTR lold+4,eax
  318 ;  return(0); }
  319         sub     ax,ax
  320         ret
  321 bailout:
  322 ;  { overflow=0; return(1); }
  323 ;       mov     overflow,0
  324         mov     ax,1
  325         ret
  326 asm386lANDbailout       endp
  327 
  328 asm386lMANHbailout      proc near
  329 ;
  330 ; equivalent to the C code:
  331 ;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
  332 ;  magnitude = fabs(new.x) + fabs(new.y);
  333 ;  if(magnitude * magnitude) >= rqlim) return(1);
  334 ;  lold = lnew;
  335 ;  return(0);
  336 ;
  337 ;  ltempsqrx = lsqr(lnew.x);
  338         push    bitshift
  339         push    DWORD PTR lnew
  340         push    DWORD PTR lnew
  341         call    FAR PTR multiply
  342         mov     WORD PTR ltempsqrx,ax
  343         mov     WORD PTR ltempsqrx+2,dx
  344 ;  ltempsqry = lsqr(lnew.y);
  345         push    bitshift
  346         push    DWORD PTR lnew+4
  347         push    DWORD PTR lnew+4
  348         call    FAR PTR multiply
  349         add     sp,20
  350         mov     WORD PTR ltempsqry,ax
  351         mov     WORD PTR ltempsqry+2,dx
  352 ;  lmagnitud = ltempsqrx + ltempsqry;
  353         mov     eax,DWORD PTR ltempsqry
  354         add     eax,DWORD PTR ltempsqrx
  355         mov     DWORD PTR lmagnitud,eax
  356 ;  lold = (abs(new.x) + abs(new.y))^2   ; lold used for storage
  357         mov     eax,DWORD PTR lnew
  358         cmp     eax,0
  359         jge     xpos    ; if negative, negate
  360         neg     eax
  361 xpos:   mov     ebx,DWORD PTR lnew+4
  362         cmp     ebx,0
  363         jge     ypos    ; if negative, negate
  364         neg     ebx
  365 ypos:   add     eax,ebx
  366         jno     oksum
  367         mov     overflow,1
  368         jmp     short bailout
  369 oksum:  mov     DWORD PTR lold,eax
  370 ;  lold * lold;
  371         push    bitshift
  372         push    DWORD PTR lold
  373         push    DWORD PTR lold
  374         call    FAR PTR multiply
  375         add     sp,10
  376 ;   put results returned in ax and dx into edx
  377         shl     edx,16
  378         mov     dx,ax
  379 ;  if ((lold * lold) >= llimit
  380         cmp     edx,DWORD PTR llimit
  381         jae     bailout
  382 ;   || overflow)
  383 chkoflow:
  384 ;       cmp     overflow,0
  385 ;       jne     bailout
  386 ;  else {
  387 ;  lold = lnew;
  388         mov     eax,DWORD PTR lnew
  389         mov     DWORD PTR lold,eax
  390         mov     eax,DWORD PTR lnew+4
  391         mov     DWORD PTR lold+4,eax
  392 ;  return(0); }
  393         sub     ax,ax
  394         ret
  395 bailout:
  396 ;  { overflow=0; return(1); }
  397 ;       mov     overflow,0
  398         mov     ax,1
  399         ret
  400 asm386lMANHbailout      endp
  401 
  402 asm386lMANRbailout      proc near
  403 ;
  404 ; equivalent to the C code:
  405 ;  ltempsqrx = lsqr(lnew.x); ltempsqry = lsqr(lnew.y);
  406 ;  magnitude = fabs(new.x + new.y);
  407 ;  if(magnitude * magnitude) >= rqlim) return(1);
  408 ;  lold = lnew;
  409 ;  return(0);
  410 ;
  411 ;  ltempsqrx = lsqr(lnew.x);
  412         push    bitshift
  413         push    DWORD PTR lnew
  414         push    DWORD PTR lnew
  415         call    FAR PTR multiply
  416         mov     WORD PTR ltempsqrx,ax
  417         mov     WORD PTR ltempsqrx+2,dx
  418 ;  ltempsqry = lsqr(lnew.y);
  419         push    bitshift
  420         push    DWORD PTR lnew+4
  421         push    DWORD PTR lnew+4
  422         call    FAR PTR multiply
  423         add     sp,20
  424         mov     WORD PTR ltempsqry,ax
  425         mov     WORD PTR ltempsqry+2,dx
  426 ;  lmagnitud = ltempsqrx + ltempsqry;
  427         mov     eax,DWORD PTR ltempsqry
  428         add     eax,DWORD PTR ltempsqrx
  429         mov     DWORD PTR lmagnitud,eax
  430 ;  lold = abs(new.x + new.y)    ; lold used as temp storage
  431         mov     eax,DWORD PTR lnew
  432         add     eax,DWORD PTR lnew+4
  433         mov     DWORD PTR lold,eax      ; square next, don't need abs
;  lold * lold;
        push    bitshift
        push    DWORD PTR lold
        push    DWORD PTR lold
        call    FAR PTR multiply
        add     sp,10
;   put results returned in ax and dx into edx
        shl     edx,16
        mov     dx,ax
;  if ((lold * lold) >= llimit
        cmp     edx,DWORD PTR llimit
        jae     bailout
;   || overflow)
chkoflow:
;       cmp     overflow,0
;       jne     bailout
;  else {
;  lold = lnew;
        mov     eax,DWORD PTR lnew
        mov     DWORD PTR lold,eax
        mov     eax,DWORD PTR lnew+4
        mov     DWORD PTR lold+4,eax
;  return(0); }
        sub     ax,ax
        ret
bailout:
;  { overflow=0; return(1); }
;       mov     overflow,0
        mov     ax,1
        ret
asm386lMANRbailout      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 FRACTALS_TEXT

        ; 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
        fstp    qword ptr new+8 ; newx
        fstp    qword ptr new   ; stack is empty
        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
        call    word ptr [floatbailout]
        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
        fstp    qword ptr new+8 ; newx
        fstp    qword ptr new   ; stack is empty
;       call    near ptr asmfloatbailout
        call    word ptr [floatbailout]
        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:
        fstp    qword ptr new+8 ; newx
        fstp    qword ptr new   ; stack is empty
;       call    near ptr asmfloatbailout
        call    word ptr [floatbailout]
        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:
        fstp    qword ptr new+8 ; newx
        fstp    qword ptr new   ; stack is empty
;       call    near ptr asmfloatbailout
        call    word ptr [floatbailout]
        ret
FBarnsley2FPFractal endp

FLambdaFPFractal proc uses si di
        ; tempsqrx and tempsqry can be used -- the C code doesn't use them!
  434         fld     tempsqry                ;oy2
  435         fsub    tempsqrx                ;oy2-ox2
  436         fld     old                     ;ox oy2-ox2
  437         fadd    st(1),st                ;ox tx=ox+oy2-ox2
  438         fadd    st,st                   ;2ox tx
  439         fld1                            ;1 2ox tx
  440         fsubr                           ;(1-2ox) tx
  441         fmul    old+8                   ;ty=oy(1-2ox) tx
  442         fld     st(1)                   ;tx ty tx -- duplicate these now
  443         fld     st(1)                   ;ty tx ty tx
  444         mov     bx,floatparm
  445         fld     qword ptr [bx+8]        ;py ty tx ty tx -- load y first
  446         fld     qword ptr [bx]          ;px py ty tx ty tx
  447         fmul    st(5),st                ;px py ty tx ty pxtx
  448         fmulp   st(4),st                ;py ty tx pxty pxtx
  449         fmul    st(2),st                ;py ty pytx pxty pxtx
  450         fmul                            ;pyty pytx pxty pxtx
  451         fsubp   st(3),st                ;pytx pxty nx=pxtx-pyty
  452         fadd                            ;ny=pxty+pytx nx
  453         fstp    qword ptr new+8 ; newx
  454         fstp    qword ptr new   ; stack is empty
  455 ;       call    near ptr asmfloatbailout
  456         call    word ptr [floatbailout]
  457         ret
  458 FLambdaFPFractal endp
  459 
  460 ; The following is no longer used.
  461 asmfloatbailout proc near
  462         ; called with new.y and new.x on stack and clears the stack
  463         ; destroys SI and DI: caller must save them
  464         fst     qword ptr new+8
  465         fmul    st,st                   ;/* ny2 nx */
  466         fst     tempsqry
  467         fxch                            ;/* nx ny2 */
  468         fst     qword ptr new
  469         fmul    st,st                   ;/* nx2 ny2 */
  470         fst     tempsqrx
  471         fadd
  472         fst     magnitude
  473         fcomp   rqlim                   ;/*** stack is empty */
  474         fstsw   ax                      ;/*** 287 and up only */
  475         sahf
  476         jae     bailout
  477         mov     si,offset new
  478         mov     di,offset old
  479         mov     ax,ds
  480         mov     es,ax
  481         mov     cx,8
  482         rep     movsw
  483         xor     ax,ax
  484         ret
  485 bailout:
  486         mov     ax,1
  487         ret
  488 asmfloatbailout endp
  489 ; The preceeding is no longer used.
  490 
  491 asmfpMODbailout proc near uses si di
  492         fld     qword ptr new+8
  493         fmul    st,st                   ;/* ny2 */
  494         fst     tempsqry
  495         fld     qword ptr new   ;/* nx ny2 */
  496         fmul    st,st                   ;/* nx2 ny2 */
  497         fst     tempsqrx
  498         fadd
  499         fst     magnitude
  500         fcomp   rqlim                   ;/*** stack is empty */
  501         fstsw   ax                      ;/*** 287 and up only */
  502         sahf
  503         jae     bailout
  504         mov     si,offset new
  505         mov     di,offset old
  506         mov     ax,ds
  507         mov     es,ax
  508         mov     cx,8
  509         rep     movsw
  510         xor     ax,ax
  511         ret
  512 bailout:
  513         mov     ax,1
  514         ret
  515 asmfpMODbailout endp
  516 
  517 asmfpREALbailout proc near uses si di
  518         fld     qword ptr new
  519         fmul    st,st                   ;/* nx2 */
  520         fst     tempsqrx
  521         fld     qword ptr new+8 ;/* ny nx2 */
  522         fmul    st,st                   ;/* ny2 nx2 */
  523         fst     tempsqry                ;/* ny2 nx2 */
  524         fadd    st,st(1)                ;/* ny2+nx2 nx2 */
  525         fstp    magnitude               ;/* nx2 */
  526         fcomp   rqlim                   ;/*** stack is empty */
  527         fstsw   ax                      ;/*** 287 and up only */
  528         sahf
  529         jae     bailout
  530         mov     si,offset new
  531         mov     di,offset old
  532         mov     ax,ds
  533         mov     es,ax
  534         mov     cx,8
  535         rep     movsw
  536         xor     ax,ax
  537         ret
  538 bailout:
  539         mov     ax,1
  540         ret
  541 asmfpREALbailout endp
  542 
  543 asmfpIMAGbailout proc near uses si di
  544         fld     qword ptr new+8
  545         fmul    st,st                   ;/* ny2 */
  546         fst     tempsqry
  547         fld     qword ptr new   ;/* nx ny2 */
  548         fmul    st,st                   ;/* nx2 ny2 */
  549         fst     tempsqrx                ;/* nx2 ny2 */
  550         fadd    st,st(1)                ;/* nx2+ny2 ny2 */
  551         fstp    magnitude               ;/* ny2 */
  552         fcomp   rqlim                   ;/*** stack is empty */
  553         fstsw   ax                      ;/*** 287 and up only */
  554         sahf
  555         jae     bailout
  556         mov     si,offset new
  557         mov     di,offset old
  558         mov     ax,ds
  559         mov     es,ax
  560         mov     cx,8
  561         rep     movsw
  562         xor     ax,ax
  563         ret
  564 bailout:
  565         mov     ax,1
  566         ret
  567 asmfpIMAGbailout endp
  568 
  569 asmfpORbailout proc near uses si di
  570         fld     qword ptr new+8
  571         fmul    st,st                   ;/* ny2 */
  572         fst     tempsqry
  573         fld     qword ptr new   ;/* nx ny2 */
  574         fmul    st,st                   ;/* nx2 ny2 */
  575         fst     tempsqrx
  576         fld     st(1)                   ;/* ny2 nx2 ny2 */
  577         fadd    st,st(1)                ;/* ny2+nx2 nx2 ny2 */
  578         fstp    magnitude               ;/* nx2 ny2 */
  579         fcomp   rqlim                   ;/* ny2 */
  580         fstsw   ax                      ;/*** 287 and up only */
  581         sahf
  582         jae     bailoutp
  583         fcomp   rqlim                   ;/*** stack is empty */
  584         fstsw   ax                      ;/*** 287 and up only */
  585         sahf
  586         jae     bailout
  587         mov     si,offset new
  588         mov     di,offset old
  589         mov     ax,ds
  590         mov     es,ax
  591         mov     cx,8
  592         rep     movsw
  593         xor     ax,ax
  594         ret
  595 bailoutp:
  596         finit           ;/* cleans up stack */
  597 bailout:
  598         mov     ax,1
  599         ret
  600 asmfpORbailout endp
  601 
  602 asmfpANDbailout proc near uses si di
  603         fld     qword ptr new+8
  604         fmul    st,st                   ;/* ny2 */
  605         fst     tempsqry
  606         fld     qword ptr new   ;/* nx ny2 */
  607         fmul    st,st                   ;/* nx2 ny2 */
  608         fst     tempsqrx
  609         fld     st(1)                   ;/* ny2 nx2 ny2 */
  610         fadd    st,st(1)                ;/* ny2+nx2 nx2 ny2 */
  611         fstp    magnitude               ;/* nx2 ny2 */
  612         fcomp   rqlim                   ;/* ny2 */
  613         fstsw   ax                      ;/*** 287 and up only */
  614         sahf
  615         jb      nobailoutp
  616         fcomp   rqlim                   ;/*** stack is empty */
  617         fstsw   ax                      ;/*** 287 and up only */
  618         sahf
  619         jae     bailout
  620         jmp     short nobailout
  621 nobailoutp:
  622         finit           ;/* cleans up stack */
  623 nobailout:
  624         mov     si,offset new
  625         mov     di,offset old
  626         mov     ax,ds
  627         mov     es,ax
  628         mov     cx,8
  629         rep     movsw
  630         xor     ax,ax
  631         ret
  632 bailout:
  633         mov     ax,1
  634         ret
  635 asmfpANDbailout endp
  636 
  637 asmfpMANHbailout proc near uses si di
  638         fld     qword ptr new+8
  639         fld     st
  640         fmul    st,st                   ;/* ny2 ny */
  641         fst     tempsqry
  642         fld     qword ptr new   ;/* nx ny2 ny */
  643         fld     st
  644         fmul    st,st                   ;/* nx2 nx ny2 ny */
  645         fst     tempsqrx
  646         faddp   st(2),st                ;/* nx nx2+ny2 ny */
  647         fxch    st(1)                   ;/* nx2+ny2 nx ny */
  648         fstp    magnitude               ;/* nx ny */
  649         fabs
  650         fxch
  651         fabs
  652         fadd                            ;/* |nx|+|ny| */
  653         fmul    st,st                   ;/* (|nx|+|ny|)2 */
  654         fcomp   rqlim                   ;/*** stack is empty */
  655         fstsw   ax                      ;/*** 287 and up only */
  656         sahf
  657         jae     bailout
  658         jmp     short nobailout
  659 nobailoutp:
  660         finit           ;/* cleans up stack */
  661 nobailout:
  662         mov     si,offset new
  663         mov     di,offset old
  664         mov     ax,ds
  665         mov     es,ax
  666         mov     cx,8
  667         rep     movsw
  668         xor     ax,ax
  669         ret
  670 bailout:
  671         mov     ax,1
  672         ret
  673 asmfpMANHbailout endp
  674 
  675 asmfpMANRbailout proc near uses si di
  676         fld     qword ptr new+8
  677         fld     st
  678         fmul    st,st                   ;/* ny2 ny */
  679         fst     tempsqry
  680         fld     qword ptr new           ;/* nx ny2 ny */
  681         fld     st
  682         fmul    st,st                   ;/* nx2 nx ny2 ny */
  683         fst     tempsqrx
  684         faddp   st(2),st                ;/* nx nx2+ny2 ny */
  685         fxch    st(1)                   ;/* nx2+ny2 nx ny */
  686         fstp    magnitude               ;/* nx ny */
  687         fadd                            ;/* nx+ny */
  688         fmul    st,st                   ; square, don't need abs
        fcomp   rqlim                   ;/*** stack is empty */
        fstsw   ax                      ;/*** 287 and up only */
        sahf
        jae     bailout
        jmp     short nobailout
nobailoutp:
        finit           ;/* cleans up stack */
nobailout:
        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
asmfpMANRbailout endp

.8086
.8087

        end