****************************************************************************
*
*         Draws a Row of Pixels in Mandelbrot Set (with smoothing)
*
*         C must set the following variables prior to call:
* 
*                xptr   :  pointer to table of x-values 
*                imagc  :  imaginary part of current pixel row
*                bp1-4  :  pointers to the four bit planes
*  
*         Integers are 2**26 times the actual values in the complex plane
*
****************************************************************************

*  First some macros we will need.....

EvalPix     MACRO
            moveq       #79,d3               set counter to 79
            clr.l       d0                   zero out real_z
            clr.l       d2                   zero out imag_z

repeat\1    moveq       #13,d7               number of bits to shift
            asr.l       d7,d0                divide real_z by 2**13
            asr.l       d7,d2                divide imag_z by 2**13
 
            move.l      d0,d1                real_z
            sub.w       d2,d0                real_z - imag_z
            add.w       d1,d1                2 * real_z
            muls        d1,d2                2 * real_z * imag_z
            sub.w       d0,d1                real_z + imag_z
            muls        d1,d0                real_z**2 - imag_z**2
           
            add.l       d5,d0                add real_c to get new real_z
            move.l      d0,d7                create temp copy of real_z
            bpl         pos_1\1              if real_z positive, do nothing
            neg.l       d7                   take absolute value of real_z
pos_1\1     add.l       d6,d2                add imag_c to get new imag_z
            move.l      d2,d1                load working copy of imag_z
            bpl         pos_2\1              if imag_z positive, do nothing
            neg.l       d1                   take absolute value of imag_z
pos_2\1     add.l       d1,d7                d7 contains the norm of z
            subq        #1,d3                decrement counter by 1
            beq         pixout\1             if 79 iters, draw the pixel
            subi.l      #200000000,d7        reduce the norm by 200 million 
            bmi         repeat\1             if z not exploding, continue
            addq        #1,d3                increment counter by 1
            asr.l       #3,d3                color is 1/8 number of iters
            addq        #3,d3                range 3 to 12
pixout\1    nop
            ENDM

* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

WritePix    MACRO
            tst.l       d4                   examine bit within byte
            bne         plane1\1             if not bit zero, poke planes
            moveq       #8,d4                reset to bit 8 (next will be 7)
            lea         1(a0),a0             incr addr within 1st bit plane
            lea         1(a1),a1                              2nd
            lea         1(a2),a2                              3rd
            lea         1(a3),a3                              4th
plane1\1    subq.l      #1,d4                decrement bit within byte by 1

nomenus\1   btst        d4,(a0)              if we've hit a menu-- STOP!
            bne         nomenus\1 
            btst        d4,(a1)
            bne         nomenus\1
            btst        d4,(a2)
            bne         nomenus\1
            btst        d4,(a3)
            bne         nomenus\1

            btst        #0,d3                examine 1st bit of color
            beq         plane2\1             if bit off, leave screen alone
            bset        d4,(a0)              turn current bit on in plane
plane2\1    btst        #1,d3              
            beq         plane3\1
            bset        d4,(a1)
plane3\1    btst        #2,d3
            beq         plane4\1
            bset        d4,(a2)
plane4\1    btst        #3,d3
            beq         writeout\1
            bset        d4,(a3)
writeout\1  nop
            ENDM

*------------------------------------------*
*           The main routine!              *
*------------------------------------------*

            XDEF        _msmooth             This tells C about us
            SECTION     text,code

_msmooth    movem.l     d2-d7/a2-a6,-(a7)    save registers
setup       moveq       #8,d4                bit within screen byte
            move.l      #638,pixct           pixel counter for current row
            move.l      _xptr,a5              
            move.l      _imagc,d6
            move.l      _bp1,a0              
            move.l      _bp2,a1
            move.l      _bp3,a2
            move.l      _bp4,a3
  
xloop       move.l      (a5),d5              move next x-value into D5

            EvalPix     0                    the i-th pixel
            move.l      d3,lastval 
            WritePix    0

            adda        #8,a5
            move.l      (a5),d5
            EvalPix     2                    the (i+2)nd pixel
            move.l      d3,nextval
            suba        #4,a5
            
            cmp         lastval,d3
            beq         nextpix
            
            move.l      (a5),d5
            EvalPix     1                    the (i+1)st pixel

nextpix     WritePix    1                         
            move.l      nextval,d3
            WritePix    2

            adda        #8,a5

next_x      subi.l      #3,pixct             decrement x counter
            bpl         xloop                if not done with row, continue

            add.l       #80,_bp1             advance to next display line
            add.l       #80,_bp2
            add.l       #80,_bp3
            add.l       #80,_bp4

            movem.l     (a7)+,d2-d7/a2-a6    restore registers
          
            rts

            SECTION     udata,bss      
            XREF        _xptr,_imagc
            XREF        _bp1,_bp2,_bp3,_bp4
pixct       DS.L        1
lastval     DS.L        1
nextval     DS.L        1
            END

