home *** CD-ROM | disk | FTP | other *** search
- ** This is the *BIG* one. Here lies 80% of the work I put into
- ** "Apfelkiste". Basically this function does the same as it's
- ** float counterpart Iter_FLOAT() in Float.c, but it uses a
- ** fix-point format for real calculations.
- ** Refer to the revision header of "Apfelkiste.c" for the exact
- ** definition.
- ** The conversion of normal floats to my format is quite easy:
- ** Multiply the float by 2**24 (doing a 24 bit shift in fact),
- ** cast to long and there you are...
- **
- ** This file needs to be assembled separately in order to recompile
- ** the whole source. I really think Lattice DOES need an inline
- ** assembly facility, or at least the workbench interface should
- ** update and link *.a files the same way it does with *.c and *.o .
-
- CSECT DATA,1,,2,2
-
- XREF _maxcol
- XREF _MAXITER
-
- CSECT TEXT,0,,1,2
-
- XDEF _Iter_FXP
-
- _Iter_FXP:
- movem.l D3-D7,-(SP)
-
- move.l D1,D3 ;(r)
- move.l D2,D4 ;(i)
- move.w _MAXITER(A4),D0
- ext.l D0 ;(count)
-
- __while:
- swap D0
- move.l D3,A1 ;save r
- tst.l D3 ;r < 0?
- bpl.s __skip1 ;no
- neg.l D3 ;yes, negate
-
- __skip1:
- move.w D3,D5 ;rl * rl -> D5
- mulu.w D3,D5
- clr.w D5 ;24 bit right shift
- swap D5
- lsr.w #8,D5
-
- move.l D3,D6 ;2 * rl * rh -> D6
- swap D6
- mulu.w D3,D6
- lsr.l #7,D6 ;7 bit only, because of factor 2!
- add.l D6,D5 ;collect in D5
-
- swap D3 ;rh * rh -> D3
- mulu.w D3,D3
- asl.l #8,D3 ;8 bit left shift
- add.l D3,D5 ;collect in D5
-
- move.l A1,D3 ;fetch r back
-
- move.l D4,A0 ;save i
- tst.l D4 ;D4 < 0?
- bpl.s __skip2 ;no
- neg.l D4 ;yes, negate
-
- __skip2:
- move.w D4,D6 ;il * il -> D6
- mulu.w D4,D6
- clr.w D6 ;24 bit right shift
- swap D6
- lsr.w #8,D6
- add.l D6,D5 ;collect in D5
-
- move.l D4,D6 ;2 * il * ih -> D6
- swap D6
- mulu.w D4,D6
- lsr.l #7,D6 ;7 bit only because of factor 2!
- add.l D6,D5 ;collect in D5
-
- swap D4 ;ih * ih -> D4
- mulu.w D4,D4
- asl.l #8,D4
- add.l D4,D5 ;collect in D5
-
- ;now D5 contains r * r + i * i
-
- cmp.l A2,D5 ;test for upper bound
- bge __done ;exceeded => end
-
- ;evaluate ( r + i ) * ( r - i ) + p -> D7
-
- ;No need to save r and i (D3 / D4), beacause they're already
- ;in A1 / A0 (well, saved another 4 machine cycles!)
-
- add.l A0,D3 ;r+i -> D3
- move.l A1,D4 ;r-i -> D4
- sub.l A0,D4
-
- tst.l D3 ;r < 0?
- bpl.s __skip3 ;no
- neg.l D3 ;yes, negate
- not.w D0 ;remember negative sign
-
- __skip3:
- tst.l D4 ;i < 0?
- bpl.s __skip4 ;no
- neg.l D4 ;yes, negate
- not.w D0 ;remember negative sign
-
- __skip4:
- move.w D3,D7 ;rl * il -> D7
- mulu.w D4,D7
- clr.w D7 ;24 bit shift
- swap D7
- lsr.w #8,D7
-
- swap D4 ;rl * ih -> D6
- move.w D4,D6
- mulu.w D3,D6
- lsr.l #8,D6 ;8 bit shift
-
- add.l D6,D7 ;collect in D7
-
- swap D3 ;rh * ih -> D6
- move.w D4,D6
- mulu.w D3,D6
- asl.l #8,D6 ;8 bit shift
- add.l D6,D7 ;collect in D7
-
- swap D4 ;rh * il -> D6
- mulu.w D3,D4
- lsr.l #8,D4 ;8 bit shift
- add.l D4,D7 ;collect in D7
-
- tst.w D0 ;correct result?
- beq.s __skip5 ;no
- neg.l D7 ;yes
- clr.w D0 ;erase marker
-
- __skip5:
- add.l D1,D7 ;add p
-
- ;evaluate 2 * r * i + q -> D5
-
- move.l A1,D3 ;call r and i back
- move.l A0,D4
-
- tst.l D3 ;r < 0?
- bpl.s __skip6 ;no
- neg.l D3 ;yes, negate
- not.w D0 ;remember negative sign
-
- __skip6:
- tst.l D4 ;i < 0?
- bpl.s __skip7 ;no
- neg.l D4 ;yes, negate
- not.w D0 ;remember negative sign
-
- __skip7:
- move.w D3,D5 ;2 * rl * il -> D5
- mulu.w D4,D5
- clr.w D5 ;23 bit shift (instead of 24, because of factor 2)
- swap D5
- lsr.w #7,D5
-
- swap D4 ;2 * rl * ih -> D6
- move.w D4,D6
- mulu.w D3,D6
- lsr.l #7,D6 ;7 bit shift (instead of 8, because of factor 2)
- add.l D6,D5 ;collect in D5
-
- swap D3 ;2 * rh * ih -> D6
- move.w D4,D6
- mulu.w D3,D6
- asl.l #8,D6 ;9 bit shift (instead of 8, because of factor 2)
- add.l D6,D6 ;add.l is 2 cycles faster as asl.l #1 !
- add.l D6,D5 ;collect in D5
-
- swap D4 ;2 * rh * il -> D6
- mulu.w D3,D4
- lsr.l #7,D4 ;7 bit shift (instead of 8, because of factor 2)
- add.l D5,D4 ;collect in D4, i = 2 * r * i
-
- tst.w D0 ;correct result?
- beq.s __skip8 ;no
- neg.l D4 ;yes
- clr.w D0 ;erase marker
-
- __skip8:
- add.l D2,D4 ;add q, i = 2 * r * i + q
-
- move.l D7,D3 ;r = ( r + i ) * ( r - i ) + p
-
- swap D0
- dbra D0,__while ;to start of loop
-
- moveq #0,D0 ;return 0, if MAXITER was exceeded
-
- movem.l (SP)+,D3-D7
- rts
-
- __done:
- swap D0
- divu.w _maxcol(A4),D0 ;return ( count % maxcol )
- clr.w D0
- swap D0
-
- movem.l (SP)+,D3-D7
- rts
-
- END
-