;JULIA 2
;-------
;A fractal generator, not orginally written by myself but now works with
;the library.

	opt	o+

	INCLUDE	"exec/exec_lib.i"
	INCLUDE	"games/games_lib.i"
	INCLUDE	"games/games.i
	INCLUDE	"hardware/custom.i"

CALL	MACRO
	jsr	_LVO\1(a6)
	ENDM

SAVEREGS MACRO
	MOVEM.L	A0-A6/D0-D7,-(SP)
	ENDM

RETURNREGS MACRO
	MOVEM.L	(SP)+,A0-A6/D0-D7
	ENDM

	SECTION	"Julia",CODE

;==========================================================================;
;                             INITIALISE DEMO
;==========================================================================;

Start:	MOVEM.L	A0-A6/D1-D7,-(SP)
	move.l	($4).w,a6
	lea	GMS_Name(pc),a1
	moveq	#$00,d0
	CALL	OpenLibrary
	move.l	d0,GMS_Base
	beq	Quit

	move.l	GMS_Base(pc),a6
	CALL	SetUserPri

	move.l	GMS_Base(pc),a6          ;Tell GMS that we want to add a
	lea	ScreenStruct(pc),a0      ;screen for use.
	CALL	Add_Screen
	tst.l	d0
	bne	Error

	lea	ScreenStruct(pc),a0      ;Now show the screen/pic.
	CALL	Show_Screen

;==========================================================================;
;
;==========================================================================;

	lea	DataArea(pc),a5
	move.l	#$fffffffe,(a5)+         ;a5 = $fffffffe+
	move.l	#$80000014,(a5)+         ;a5 = mask & word per raster count

StartJulia:
	move.l	ScreenStruct+SS_MemPtr1(pc),a0 ;get pointer to bitplanes

.waitb	btst.b	#6,$dff000+dmaconr
	bne.b	.waitb
	move.l	a0,$dff000+bltdpt
	move.l	#$01000000,$dff000+bltcon0
	clr.w	$dff000+bltdmod
	move.w	#(640*64)+40,$dff000+bltsize ;256*40*5 bytes

	lea	JuliaData(pc),a6
	move.l	(a6)+,(a5)               ;a5 = ?

.JuliaFound
	move.w	(a5),MValue              ;initial m
	move.w	(a6),PixStep             ;pixel step
	move.w	(a6)+,RastStep           ;raster step
	move.l	(a6)+,C1C2               ;initial c1 and c2
	move.w	#256,LinesLeft(a5)       ;vertical height
	lea	256*40(a0),a1
	lea	256*40(a1),a2
	lea	256*40(a2),a3
	lea	$04000000,a6             ;for magnitude test

	lea	256*40(a3),a4

	MOVE.L	A6,-(SP)
	move.l	GMS_Base(pc),a6
	CALL	Wait_OSVBL
	MOVE.L	(SP)+,A6

PixelLoop:
	move.w	(a5),d1                  ;d1 = Initial X
	move.w	InitialY(a5),d0          ;d0 = Initial Y
	moveq	#30,d7                   ;d7 = 30.
	movem.w	C1C2(pc),d4-d5           ;MA : d4/d5 = C1/C2
	move.w	d0,d2                    ;d2 = Initial Y
	move.w	d1,d3                    ;d3 = Initial X
	bra.s	CheckMagnitude

IterateJulia:
	sub.l	d3,d2                    ;x^2 - y^2
	lsl.l	#4,d2                    ;fix decimal point
	swap	d2                       ;...
	add.w	d4,d2                    ;x1 = x^2 - y^2 + c1

	move.w	d1,d3                    ;y
	muls	d0,d3                    ;x * y
	lsl.l	#5,d3                    ;fix decimal point and multiply by 2
	swap	d3                       ;...
	add.w	d5,d3                    ;y1 = 2 * x * y + c2

	move.w	d2,d0                    ;x = x1
	move.w	d3,d1                    ;y = y1

CheckMagnitude:
	muls	d2,d2                    ;x^2
	muls	d3,d3                    ;y^2
	move.l	d2,d6
	add.l	d3,d6                    ;z = x^2 + y^2
	cmp.l	a6,d6                    ;escaped yet?
	dbhi	d7,IterateJulia
	move.w	PixelMask(a5),d6
	moveq	#0,d5
	move.b	JumpTable+1(pc,d7.w),d5
	jmp	JumpTable(pc,d5.w)

JumpTable:
	dc.b	Plot00-JumpTable,Plot31-JumpTable
	dc.b	Plot30-JumpTable,Plot29-JumpTable
	dc.b	Plot28-JumpTable,Plot27-JumpTable
	dc.b	Plot26-JumpTable,Plot25-JumpTable
	dc.b	Plot24-JumpTable,Plot23-JumpTable
	dc.b	Plot22-JumpTable,Plot21-JumpTable
	dc.b	Plot20-JumpTable,Plot19-JumpTable
	dc.b	Plot18-JumpTable,Plot01-JumpTable
	dc.b	Plot16-JumpTable,Plot15-JumpTable
	dc.b	Plot14-JumpTable,Plot13-JumpTable
	dc.b	Plot12-JumpTable,Plot11-JumpTable
	dc.b	Plot10-JumpTable,Plot09-JumpTable
	dc.b	Plot08-JumpTable,Plot07-JumpTable
	dc.b	Plot06-JumpTable,Plot05-JumpTable
	dc.b	Plot04-JumpTable,Plot03-JumpTable
	dc.b	Plot02-JumpTable,Plot17-JumpTable

Plot22:	or.w	d6,(a4)
	or.w	d6,(a2)
	or.w	d6,(a1)
	bra.b	Plot00

Plot21:	or.w	d6,(a4)
	or.w	d6,(a2)
	or.w	d6,(a0)
	bra.b	Plot00

Plot20:	or.w	d6,(a4)
	or.w	d6,(a2)
	bra.b	Plot00

Plot18:	or.w	d6,(a4)
	or.w	d6,(a1)
	bra.b	Plot00

Plot26:	or.w	d6,(a4)
Plot10:	or.w	d6,(a3)
	or.w	d6,(a1)
	bra.b	Plot00

Plot23:	or.w	d6,(a4)
	or.w	d6,(a2)
	or.w	d6,(a1)
	or.w	d6,(a0)
	bra.b	Plot00

Plot19:	or.w	d6,(a4)
	or.w	d6,(a1)
	or.w	d6,(a0)
	bra.b	Plot00

Plot27:	or.w	d6,(a4)
Plot11:	or.w	d6,(a3)
	or.w	d6,(a1)
	or.w	d6,(a0)
	bra.b	Plot00

Plot17:	or.w	d6,(a4)
	or.w	d6,(a0)
	bra.b	Plot00

Plot25:	or.w	d6,(a4)
Plot09:	or.w	d6,(a3)
	or.w	d6,(a0)
	bra.b	Plot00

Plot29:	or.w	d6,(a4)
Plot13:	or.w	d6,(a3)
Plot05:	or.w	d6,(a2)
	or.w	d6,(a0)
	bra.b	Plot00

Plot16:	or.w	d6,(a4)
	bra.b	Plot00

Plot24:	or.w	d6,(a4)
Plot08:	or.w	d6,(a3)
	bra.b	Plot00

Plot28:	or.w	d6,(a4)
Plot12:	or.w	d6,(a3)
Plot04:	or.w	d6,(a2)
	bra.b	Plot00

Plot30:	or.w	d6,(a4)
Plot14:	or.w	d6,(a3)
Plot06:	or.w	d6,(a2)
Plot02:	or.w	d6,(a1)
	bra.b	Plot00

Plot31:	or.w	d6,(a4)
Plot15:	or.w	d6,(a3)
Plot07:	or.w	d6,(a2)
Plot03:	or.w	d6,(a1)
Plot01:	or.w	d6,(a0)

Plot00:	MOVE.L	D0,-(SP)
	move.w	PixStep(pc),d0
	add.w	d0,(a5)                  ;pixel "step"
	MOVE.L	(SP)+,D0

	ror.w	PixelMask(a5)            ;shift mask over
	bpl.w	PixelLoop

	addq.w	#2,a0
	addq.w	#2,a1
	addq.w	#2,a2
	addq.w	#2,a3
	addq.w	#2,a4
	subq.w	#1,WordsInRaster(a5)     ; subtract from word counter
	bne.w	PixelLoop

	MOVE.L	A6,-(SP)
	move.l	GMS_Base(pc),a6
	CALL	AutoOSReturn
	MOVE.L	(SP)+,A6

	btst.b	#6,$bfe001
	beq.b	Exit

	move.w	#320/16,WordsInRaster(a5) ; words per raster
	btst.b	#2,$dff016               ; new julia?
	beq.b	NewJulia

RasterInit:
	move.w	MValue(pc),(a5)          ; inital M value
RasterAdd:
	MOVE.L	D0,-(SP)
	move.w	RastStep(pc),d0
	add.w	d0,InitialY(a5)          ; raster "step"
	MOVE.L	(SP)+,D0
	subq.w	#1,LinesLeft(a5)
	bne.w	PixelLoop

WaitMouse:
	btst.b	#6,$bfe001
	beq.b	Exit
	btst.b	#2,$dff016
	bne.b	WaitMouse

NewJulia:
	btst.b	#2,$dff016
	beq.b	NewJulia
	bra.w	StartJulia

;===========================================================================;
;                              RETURN TO DOS
;===========================================================================;

Exit:	move.l	GMS_Base(pc),a6
	lea	ScreenStruct(pc),a0
	CALL	Delete_Screen            ;Give back screen memory etc.
Error	move.l	GMS_Base(pc),a1
	move.l	($4).w,a6
	CALL	CloseLibrary
Quit	MOVEM.L	(SP)+,A0-A6/D1-D7
	moveq	#$00,d0
	rts

;===========================================================================;
;                                  DATA
;===========================================================================;

MValue:	  dc.w	0
PixStep:  dc.w	0
RastStep: dc.w	0
C1C2:	  dc.l	0

GMS_Name:
	dc.b	"games.library",0
	even
GMS_Base:
	dc.l	0

AMT_PLANES =	5

ScreenStruct:
	dc.l	"GSV1",0
	dc.l	0,0,0            ;Screen_Mem1/2/3
	dc.l	0                ;Screen link.
	dc.l	ScreenPalette    ;Address of screen palette.
	dc.l	0                ;Address of rasterlist.
	dc.l	0                ;Amt of colours in palette.
	dc.w	320,256,320,256  ;Screen & Pic Height/Width.
	dc.w	AMT_PLANES       ;Amt_Planes
	dc.w	0,0              ;Top Of Screen, X/Y
	dc.w	0,0              ;X/Y counters (for scrolling).
	dc.l	0                ;Special attributes.
	dc.w	LORES            ;Screen mode.
	dc.b	PLANAR           ;Screen type
	dc.b	0                ;Reserved
	even

ScreenPalette:
	dc.w	$0000,$0831,$000e,$000d,$000c,$000b,$000a,$0009
	dc.w	$0008,$0007,$0106,$0205,$0304,$0403,$0502,$0611
	dc.w	$0720,$000f,$0942,$0a53,$0b64,$0c75,$0d86,$0c97
	dc.w	$0ba8,$0a9a,$098b,$0879,$0767,$0555,$0343,$0131

JuliaData:
	dc.l	$f800eb00
	dc.w	$0018,$0100,$0ad0,$ec00
	dc.l	$fd21eeae
	dc.w	$0225,$000d,$f420,$fd43


	dc.l	$ef000010
	dc.w	$0600,$0100,$f226,$fd56

	dc.l	$0015ee00
	dc.w	$fb40,$ede2,$f0b2,$001d

	dc.l	$05c0ff00
	dc.w	$ef12,$e812,$001d,$f320
	dc.l	$00000000


	rsset	-4
PixelMask	rs.w   1	;mask to "OR" with bitplanes
WordsInRaster	rs.w   1	;number of words left in current raster
InitialX	rs.w   1	;inital x
InitialY	rs.w   1	;inital y
LinesLeft	rs.w   1	;number of lines left to draw

	dc.l	0
DataArea:
	ds.b	40
