home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d5xx
/
d566
/
apfelkiste.lha
/
Apfelkiste
/
Apfelkiste2.0
/
Source
/
Apfelkiste2.0src.lzh
/
Fixpoint000.a
< prev
next >
Wrap
Text File
|
1991-07-21
|
4KB
|
211 lines
** 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