***********************************
* TurboMandel Assembler Functions *
***********************************

	CSECT data

	XREF _GfxBase
	XREF _MathTransBase
   XREF _MathBase
	XREF _CycleOn
	XREF _CurrSpeed
	XREF _CycleLeft
	XREF _Palette
	XREF _Manvp
	XREF _CycleSpeed
	XREF _toppos

   CSECT text

   XREF _LVOWaitTOF
   XREF _LVOSPMul
   XREF _LVOSPAdd
   XREF _LVOSPSub
   XREF _LVOSPCmp
   XREF _LVOSPTieee
   XREF _LVOSPFieee
	XREF _LVOLoadRGB4
	XREF _CXV45
	XREF _CXV54

   XDEF _F2I
   XDEF _I2F
	XDEF _Int32Mand_asm
	XDEF _FloatMand_asm
	XDEF _DoCycle_asm
	XDEF _PaletteLeft
	XDEF _PaletteRight

*	Int32Mand_asm (long,long,LONG);
*                 A0   A1   D0

_Int32Mand_asm:
   movem.l d2-d7/a2-a6,-(a7)
	move.l d0,d3
   moveq #0,d4            ; q1 = 0
   moveq #0,d5            ; q2 = 0
   moveq #0,d6            ; x  = 0
   moveq #0,d7            ; y  = 0
   subq.w #1,d3
mandelloop2:
   move.l d6,d1           ; D1 = oldx;
   move.l d4,d6
   sub.l d5,d6
   add.l a0,d6            ; x(D6) = q1(D4) - q2(D5) + acoo(A0);
   move.l d1,d2
   bpl.s Pos1
   neg.l d1
Pos1:
   eor.l d7,d2
   tst.l d7
   bpl.s Pos2
   neg.l d7
Pos2:
   move.l d1,d0
   swap d0
   move.w d0,d2
   mulu d7,d0
   clr.w d0
   swap d0
   swap d7
   mulu d7,d1
   clr.w d1
   swap d1
   mulu d2,d7
   add.l d0,d7
   add.l d1,d7
   tst.l d2
   bpl.s Pos3
   neg.l d7
Pos3:
   moveq #6,d0
   asl.l d0,d7
   add.l a1,d7            ; y(D7) = 2 * oldx(D1) * y(D7) + bcoo(A1);
   moveq #5,d0
   move.l d7,d5
   bpl.s Pos4
   neg.l d5
Pos4:
   move.l d5,d2
   swap d5
   mulu d5,d2
   clr.w d2
   swap d2
   mulu d5,d5
   add.l d2,d5
   add.l d2,d5
   asl.l d0,d5            ; q2(D4) = y(D7)^2;
   bvs.s mandelexit
   move.l d6,d4
   bpl.s Pos5
   neg.l d4
Pos5:
   move.l d4,d2
   swap d4
   mulu d4,d2
   clr.w d2
   swap d2
   mulu d4,d4
   add.l d2,d4
   add.l d2,d4
   asl.l d0,d4            ; q1(D4) = x(D6)^2;
   bvs.s mandelexit
   move.l d4,d0
   add.l d5,d0
   bvs.s mandelexit
   cmp.l #536870912,d0
   bgt.s mandelexit
   dbf d3,mandelloop2
   moveq #1,d3
mandelexit:
   subq.w #1,d3
   move.l d3,d0
   movem.l (a7)+,d2-d7/a2-a6
	rts

* LONG __asm FloatMand_asm (float,float,LONG);
* D0                        A0    A1    D0

_FloatMand_asm:
   movem.l d2-d7/a2-a6,-(a7)         ; /* Calculate iteration of point */
	move.l a0,_acoo
	move.l a1,_bcoo
	move.l d0,d3
   move.l _MathBase(a4),a6
   moveq #0,d4            ; q1
   moveq #0,d5            ; q2
   moveq #0,d6            ; x
   moveq #0,d7            ; y
   subq.w #1,d3
mandelloop:
   move.l d4,d0
   move.l d5,d1
   jsr _LVOSPSub(a6)      ; d0 = q1 - q2;
   move.l _acoo(PC),d1
   jsr _LVOSPAdd(a6)
   move.l d6,d1           ; lastx = x
   move.l d0,d6           ; x = q1 - q2 + a;
   move.l d7,d0
   jsr _LVOSPMul(a6)      ; d0 = lastx * y;
   addq.b #1,d0           ;   move.l   d0,d1 
                          ;   jsr      _LVOSPAdd(a6)   ; d0 = 2 * lastx * y;
   move.l _bcoo(PC),d1
   jsr _LVOSPAdd(a6)
   move.l d0,d7           ; y = 2 * lastx * y + b;
   move.l d0,d1
   jsr _LVOSPMul(a6)      ; q2 = y * y;
   move.l d0,d5
   move.l d6,d0           ; d0 = x;
   move.l d0,d1
   jsr _LVOSPMul(a6)      ; q1 = x * x;
   move.l d0,d4
   move.l d5,d1
   jsr _LVOSPAdd(a6)      ; d0 = q1 + q2;
   move.l #$80000043,d1
   jsr _LVOSPCmp(a6)
   bgt.s leavemandel      ; if (q1 + q2 > 4.0) goto leavemandel;
   dbf d3,mandelloop
   moveq #1,d3
leavemandel:
   subq.w #1,d3
   move.l d3,d0
   movem.l (a7)+,d2-d7/a2-a6
	rts

_acoo:	dc.l 0
_bcoo:	dc.l 0

* void DoCycle_asm

_DoCycle_asm:
Forever:
	move.l _GfxBase(a4),a6
   jsr _LVOWaitTOF(a6)
   move.w _CycleOn(a4),d0
   beq ExitCycle
CyclePalette:
   move.w _CurrSpeed(a4),d0
   subq.w #1,d0
   bne.s NoCycle
   tst.w _CycleLeft(a4)
   beq.s CycleRight
   bsr.s PaletteLeft
   bra.s SetColors
CycleRight:
   bsr.s PaletteRight
SetColors:
   lea _Palette(a4),a1
   move.l _Manvp(a4),a0
	moveq #32,d0
	move.l _GfxBase(a4),a6
   jsr _LVOLoadRGB4(a6)
   move.w _CycleSpeed(a4),d0
NoCycle:
   move.w d0,_CurrSpeed(a4)
   bra.s Forever
PaletteLeft:
   lea _Palette(a4),a1
   move.w 8(a1),d2
   move.w #8,d3
   moveq #26,d7
CycleLoop:
   move.w 2(a1,d3.l),0(a1,d3.l)
   addq.l #2,d3
   dbf d7,CycleLoop
   move.w d2,62(a1)
   lea _toppos(a4),a1
   moveq #2,d7
TopLeft:
   move.w (a1),d0
   subq.w #1,d0
   cmp.w #3,d0
   bne.s Ok2
   moveq #31,d0
Ok2:
   move.w d0,(a1)+
   dbf d7,TopLeft
   rts
PaletteRight:
   lea _Palette(a4),a1
   move.w 62(a1),d2
   move.w #62,d3
   moveq #26,d7
CycleLoop2:
   move.w -2(a1,d3.l),0(a1,d3.l)
   subq.l #2,d3
   dbf d7,CycleLoop2
   move.w d2,8(a1)
   lea _toppos(a4),a1
   moveq #2,d7
TopRight:
   move.w (a1),d0
   addq.w #1,d0
   cmp.w #32,d0
   bne.s Ok1
   moveq #4,d0
Ok1:
   move.w d0,(a1)+
   dbf d7,TopRight
ExitCycle:
   rts

_PaletteLeft:
	movem.l d2/d3/d7/a1,-(a7)
	jsr PaletteLeft
	movem.l (a7)+,d2/d3/d7/a1
	rts

_PaletteRight:
	movem.l d2/d3/d7/a1,-(a7)
	jsr PaletteRight
	movem.l (a7)+,d2/d3/d7/a1
	rts

* FFP-IEEE conversions *

* void F2I (ULONG *ieee,float getal)
*       	   A0          D0
_F2I:
	move.l a3,-(a7)
	move.l a0,a3
	movea.l _MathTransBase(a4),a6
	jsr _LVOSPTieee(a6)
	jsr _CXV45(PC)								; convert single ieee to double ieee
	movem.l d0-d1,(a3)
	movea.l (a7)+,a3
	rts

* float I2F (ULONG *ieee)
* D0         A0
_I2F:
	movem.l (a0),d0-d1
	jsr _CXV54(PC)								; convert double ieee to single ieee
	movea.l   _MathTransBase(a4),a6
	jsr       _LVOSPFieee(a6)
	rts	

	END
