	SECTION		chipmemory,data_c	

							;BY BLAINE EVANS
							;1 ERITH WAY
							;PONTYBODKIN
							;NR MOLD
							;CLWYD
							;CH7 4TR
							;TEL O352-771673
	opt	c-,d+

Height			equ		256
Width			equ		40
Depth			equ		3

ScreenSize		equ		Height*Width

BobHeight		equ		26
BobWidth		equ		3
BobDepth		equ		3

BobSize			equ		BobHeight*(BobWidth*2)

	move.l	4.w,a6			;FIND EXEC BASE
	lea	gfxlib(pc),a1		;LOAD GRAPHICS LIBRARY IN A1
	moveq	#$00,d0			;VERSION 0
	jsr	-552(a6)		;OPEN LIBRARY
	move.l	d0,_gfxbase		;STORE D0 (GFX ADDRESS )
	beq	nolib_exit		;ELSE EXIT
	bsr	Foreground_addresses	;BRANCH TO FOREGROUND ADDRESSES
	bsr	Replace_Screen
	bsr	Replace_Screen_2
	bsr	Init
	bsr	FirstPosition
	move.l	#Buffer2,Buffer
	bsr	FirstPosition_2
	lea	$dff000,a6
	move.l	_gfxbase,a0		;LOAD ADDRESS OF GRAPHICS LIB IN A0
	move.l	50(a0),Oldcop		;STORE CURRENT COPPER,ETC TO RETRIEVE LATER
S
	move.l	#Newcop,50(a0)		;POINT TO OUR COPPERLIST

Wait					;WAIT LOOP
	cmp.b	#255,$dff006		;VERTICAL BLANKING GAP 
	bne.s	wait			;
;	move.w	#$fff,$180(a6)		;REMOVE TO MEASURE RASTER TIME
	bsr	Double_Buffer
	bsr	Bob_Routine
;	move.w	#$000,$180(a6)		;REMOVE TO MEASURE RASTER TIME
	btst	#$6,$bfe001		;QUIT LEFT MOUSE PRESSED
	bne.s	Wait			;ELSE LOOP TO WAIT
ended					
	move.l	_gfxbase,a0		;LOAD GRAPHICS LIB ADDRESS IN A0
	move.l	oldcop,50(a0)		;RESTORE OLD COPPER TO RETURN TO EDITTER
nomem_exit	
	move.l	4.w,a6			;FIND EXEC BASE
	move.l	_gfxbase,a1		;LOAD GRAPHICS BASE IN A1
	jsr	-414(a6)		;CLOSE LIBRARY
nolib_exit
	rts				;RETURN TO EDITER
Foreground_addresses			;START OF FOREGROUND DATA
	move.l	#Foreground,d0
	move.w	d0,Bpl0ptl		;LOW WORD IN BIT PLANE 0 LOW
	swap	d0				
	move.w	d0,Bpl0pth		;HIGH WORD IN BIT PLANE 0 HIGH
	swap	d0
	add.l	#ScreenSize,d0
	move.w	d0,Bpl1ptl		;LOW WORD IN BIT PLANE 1 LOW
	swap	d0				
	move.w	d0,Bpl1pth		;HIGH WORD IN BIT PLANE 1 HIGH
	swap	d0
	add.l	#ScreenSize,d0
	move.w	d0,Bpl2ptl		;LOW WORD IN BIT PLANE 2 LOW
	swap	d0				
	move.w	d0,Bpl2pth		;HIGH WORD IN BIT PLANE 2 HIGH
	swap	d0
	rts
Init					; initialise some variables
	move.l	#$0,Bltcon
	lea	MapX,a0
	move.l	a0,X
	move.l	#Buffer1,Buffer		; blit to screen that is not showing
	move.l	#Foreground_2,d1
	move.l	d1,NOTADDRESS		; i.e NOTADDRESS
	move.l	#Foreground,d1
	move.l	d1,SHOWNADDRESS
	move.l	#LastX1,LastX
	move.l	#LastY1,LastY
	move.l	#CurrentX1,CurrentX
	move.l	#CurrentY1,CurrentY
	move.w	#0,BuffCount
	move.l	#$0000ffff,Speed
	rts
Bob_Routine
	bsr	Delay
	bsr	LastPosition
	bsr	SpecialChars
	bsr	BlitScreen_1
	rts

BlitScreen_1
	move.l	NOTADDRESS,a3
	add.w	Offset,a3			* add to base address
	move.l	a3,BobAddress		* base address
	bsr	SaveBackground
	bsr	OrBob
	rts

Double_Buffer
	addi.w	#1,BuffCount
	cmpi.w	#2,BuffCount
	beq	Swap_Screen
	move.l	#Foreground_2,d0
	move.l	d0,SHOWNADDRESS
	move.l	#Foreground,d1
	move.l	d1,NOTADDRESS
	move.l	#Buffer1,Buffer
	move.l	#LastX1,LastX
	move.l	#LastY1,LastY
	bsr	InsertPlanes
	rts
InsertPlanes
	move.w	d0,Bpl0ptl		;LOW WORD IN BIT PLANE 0 LOW
	swap	d0				
	move.w	d0,Bpl0pth		;HIGH WORD IN BIT PLANE 0 HIGH
	swap	d0
	add.l	#ScreenSize,d0
	move.w	d0,Bpl1ptl		;LOW WORD IN BIT PLANE 2 LOW
	swap	d0				
	move.w	d0,Bpl1pth		;HIGH WORD IN BIT PLANE 2 HIGH
	swap	d0
	add.l	#ScreenSize,d0
	move.w	d0,Bpl2ptl		;LOW WORD IN BIT PLANE 4 LOW
	swap	d0				
	move.w	d0,Bpl2pth		;HIGH WORD IN BIT PLANE 4 HIGH
	swap	d0
	rts
Swap_Screen
	move.w	#0,BuffCount
	move.l	#Foreground,d0
	move.l	d0,SHOWNADDRESS
	move.l	#Foreground_2,d1
	move.l	d1,NOTADDRESS
	move.l	#Buffer2,Buffer
	move.l	#LastX2,LastX
	move.l	#LastY2,LastY
	bsr	InsertPlanes
	rts
Delay
	move.l	Speed,d0
Del	dbra	d0,Del
	rts

ReplaceBob
	move.w	#(BobDepth)-1,d7	* no of planes -1
	lea	$dff000,a6		* custom base
	move.l	Buffer,a2
	move.l	BobAddress,a3
Replace_loop
	bsr	Replace_Bob		
	lea	BobSize(a2),a2	*find next plane
	lea	ScreenSize(a3),a3
	dbra	d7,Replace_loop
	rts
Replace_Bob				* LOAD BLITTER WITH VALUES
	bsr	Wfblit
	move.l	a2,$50(a6)		* bltapt   * Source
	move.l	a3,$54(a6)		* bltdpt   * Designation
	move.w	#0,$64(a6)		* bltamod  * Source Modula
	move.w	#Width-(BobWidth*2),$66(a6)* bltdmod  * Designation Modula
	move.l	#$09f00000,$40(a6)	* bltcon0  * Bplcon0
	move.l	#00,$42(a6)		* bltcon1  * Bplcon1
	move.w	#$ffff,$44(a6)		* bltafwm  * first word mask
	move.w	#$ffff,$46(a6)		* bltalwm  * last word mask
	move.w	#(BobHeight*64)+(BobWidth),$58(a6)* bltsize  * Bltsize
	rts

SaveBackground
	move.w	#(BobDepth)-1,d7	* no of planes -1
	lea	$dff000,a6		* custom base
	move.l	Buffer,a3
	move.l	BobAddress,a2
Save_loop
	bsr	Save_Bob		
	lea	ScreenSize(a2),a2
	lea	BobSize(a3),a3	*find next plane
	dbra	d7,Save_loop
	rts
Save_Bob				* LOAD BLITTER WITH VALUES
	bsr	Wfblit
	move.l	a2,$50(a6)		* bltapt   * Source
	move.l	a3,$54(a6)		* bltdpt   * Designation
	move.w	#Width-(BobWidth*2),$64(a6)* bltamod  * Source Modula
	move.w	#0,$66(a6)* bltdmod  * Designation Modula
	move.l	#$09f00000,$40(a6)	* bltcon0  * Bplcon0
	move.l	#00,$42(a6)		* bltcon1  * Bplcon1
	move.w	#$ffff,$44(a6)		* bltafwm  * first word mask
	move.w	#$ffff,$46(a6)		* bltalwm  * last word mask
	move.w	#(BobHeight*64)+(BobWidth),$58(a6)	* bltsize  * Bltsize
	rts
OrBob
	move.l	Bltcon,d0
	or.l	#$0fca0000,d0
	move.w	#(BobDepth)-1,d7	* no of planes -1
	lea	$dff000,a6		* custom base
	move.l	#Mask,a4
	move.l	#Bob,a2
	move.l	Buffer,a1
	move.l	BobAddress,a3
Or_loop
	bsr	Or_Bob		
	lea	BobSize(a2),a2		*find next plane
	lea	BobSize(a1),a1		*find next plane
	lea	ScreenSize(a3),a3
	dbra	d7,Or_loop
	rts
Or_Bob					* LOAD BLITTER WITH VALUES
	bsr	Wfblit
	move.l	a4,$50(a6)		* bltapt   * Mask
	move.l	a2,$4c(a6)		* Bltbpt   * Source
	move.l	a1,$48(a6)		* bltcpt   * Background
	move.l	a3,$54(a6)		* bltdpt   * Designation
	move.w	#0,$64(a6)		* bltamod  * mask Modula
	move.w	#0,$62(a6)		* bltbmod  * source Modula
	move.w	#0,$60(a6)		* bltcmod  * Designation Modula
	move.w	#Width-(BobWidth*2),$66(a6)* bltdmod  * Designation Modula
	move.l	d0,$40(a6)		* bltcon0  * Bplcon0
	move.l	d0,d1
	and.l	#$f0000000,d1		* mask out all but bit 15
	move.l	d1,$42(a6)		* bltcon1  * Bplcon1
	move.w	#$ffff,$44(a6)		* bltafwm  * first word mask
	move.w	#$0000,$46(a6)		* bltalwm  * last word mask
	move.w	#(BobHeight*64)+(BobWidth),$58(a6)	* bltsize  * Bltsize
	rts

Wfblit
	btst	#14,2(a6)		* dmaconr
	bne.s	Wfblit			* Test Blitter State
	rts	

Replace_Screen				; replace graphics
	move.l	#Foreground,a0		; load address
	move.l	#Graphics,a1		; graphics
	move.l	#((ScreenSize/4)*Depth)-1,d1	
Replace
	move.l	(a1)+,(a0)+		
	dbra	d1,Replace
	rts	
Replace_Screen_2				; replace graphics
	move.l	#Foreground_2,a0		; load address
	move.l	#Graphics,a1		; graphics
	move.l	#((ScreenSize/4)*Depth)-1,d1	
Replace_2
	move.l	(a1)+,(a0)+		
	dbra	d1,Replace_2
	rts	
FirstPosition
	moveq.l	#0,d0			* clear d0
	moveq.l	#0,d1			* clear d1
	move.l	#LastX1,a0
	move.l	#LastY1,a1
	move.w	(a0)+,d0
	move.w	(a1)+,d1
	bsr	CordToPixels
	move.l	NOTADDRESS,a3
	add.w	Offset,a3		* add to base address
	move.l	a3,BobAddress		* base address
	move.l	#Buffer1,Buffer
	bsr	SaveBackground
	rts
FirstPosition_2
	moveq.l	#0,d0			* clear d0
	moveq.l	#0,d1			* clear d1
	move.l	#LastX2,a0
	move.l	#LastY2,a1
	move.w	(a0)+,d0
	move.w	(a1)+,d1
	bsr	CordToPixels
	move.l	SHOWNADDRESS,a3
	add.w	Offset,a3		* add to base address
	move.l	a3,BobAddress		* base address
	move.l	#Buffer2,Buffer
	bsr	SaveBackground
	rts
LastPosition
	moveq.l	#0,d0			* clear d0
	moveq.l	#0,d1			* clear d1
	move.l	LastX,a0
	move.l	LastY,a1
	move.w	(a0)+,d0
	move.w	(a1)+,d1
	bsr	CordToPixels
	move.l	NOTADDRESS,a3
	add.w	Offset,a3		* add to base address
	move.l	a3,BobAddress		* base address
	bsr	ReplaceBob
	rts
SpecialChars
	moveq.l	#0,d0			* clear d0
	moveq.l	#0,d1			* clear d1
	move.l	X,a0
NoLoop
	move.w	(a0)+,d0
	cmp.w	#End,d0			* end marker ?
	bne	NoReset			* yes,then reload
	lea	MapX,a0
	move.l	a0,X
	move.w	(a0)+,d0
NoReset	
	cmp.w	#Relative,d0			;$ee01
	beq	YesRelative
	cmp.w	#Absolute,d0			;$ee00
	beq	YesAbsolute	
	cmp.w	#CoorLoop,d0			;$ee02
	beq	YesCoordLoop
	cmp.w	#LoopBack,d0			;$ee03
	beq	YesLoopBack
	cmp.w	#ChangeSpeed,d0			;$ee04
	beq	YesSpeedChange
	bsr	Mode
	rts
YesSpeedChange
	move.l	(a0)+,d0
	move.l	d0,Speed			; store speed
	bra	NoLoop				; back to move bob
	rts	
YesAbsolute
	move.w	#1,AbsFlag			; absolute mode
	move.w	#0,RelFlag			; clear relative mode
	move.w	(a0)+,d0			; 
	bsr	Mode				; find mode
	rts
YesRelative
	move.w	#1,RelFlag
	move.w	#0,AbsFlag
	move.w	(a0)+,d0
	bsr	Mode
	rts
YesCoordLoop
	move.w	(a0)+,Repeat
	sub.w	#1,Repeat
	move.w	Repeat,d5			; d5 must not be corrupted
	move.l	a0,LoopSave
	bra	NoLoop
	rts
YesLoopBack
	cmp.w	#0,Repeat
	beq	NoLoop
	move.l	LoopSave,a0
	dbra	d5,NoLoop
	move.w	#0,Repeat
	bra	NoLoop
	rts
Mode					; absolute or relative mode
	cmp.w	#1,AbsFlag			
	beq	AbsoluteMode
	cmp.w	#1,RelFlag
	beq	RelativeMode
	rts
AbsoluteMode
	move.w	(a0)+,d1		; x co-ordinate
	bsr	Position
	rts
RelativeMode
	move.w	(a0)+,d1		; x co-ordinate
	move.l	CurrentX,a2		 
	move.l	CurrentY,a3
	add.w	(a2),d0			; store
	add.w	(a3),d1
	bsr	Position
	rts
Position
	move.l	a0,X			; store pos in map
	move.l	LastX,a2		; last pos
	move.l	LastY,a3
	move.w	d0,(a2)			; store
	move.w	d1,(a3)
	move.l	CurrentX,a2		; current
	move.l	CurrentY,a3	
	move.w	d0,(a2)			; store
	move.w	d1,(a3)
	bsr	CordToPixels
	rts
CordToPixels
	divu	#16,d0			* this gives no of words in lower
					* word and remainder is shift value
					* in higher word
	move.w	d0,d2
	asl.w	#1,d2
	mulu.w	#Width,d1		* find screen address
	add.w	d2,d1			* add X to Y
	move.l	#Foreground,a3		* base address
	add.w	d1,a3			* add to base address
	move.w	d1,Offset
	move.l	a3,BobAddress		* base address
	swap	d0			* work out shift value
	ror.w	#4,d0			* and put in correct place
	swap	d0			* 
	move.w	#0,d0			* clear lower word
	move.l	d0,Bltcon
	rts

gfxlib	dc.b	"graphics.library",0	
	even
_gfxbase	dc.l	0		;LONG WORD TO STORE GFX ADDRESS
oldcop		dc.l	0		;OLD COPPERLIST ADDRESS
BobAddress	dc.l	0
Bltcon		dc.l	0
X		dc.l	0
Y		dc.l	0
LoopSave	dc.l	0
NOTADDRESS	dc.l	0
SHOWNADDRESS	dc.l	0
Buffer		dc.l	0
Offset		dc.l	0
LastX		dc.l	0
LastY		dc.l	0
CurrentX	dc.l	0
CurrentY	dc.l	0
Speed		dc.l	0
gra_base	dc.l	0
gra_base_scroll	dc.l	0
inc_2		dc.w	0
count_scroll2	dc.b	0
blit_count_scroll	dc.b	0
BuffCount	dc.w	0
RelFlag		dc.w	0
AbsFlag		dc.w	0
LoopFlag	dc.w	0
Repeat		dc.w	0
	even


Newcop
	dc.w	$0100,%0011001000000000		;3 PLANES 
	dc.w	$0102
Scroll	dc.w	$0000				;SCROLL VALUE
	dc.w	$0104,%0000000000000001		;PRIORITIES
	dc.w	$0108,$0000,$010a,$0000		;MODULAS
	dc.w	$0092,$0038,$0094,$00d0		;SCREEN
	dc.w	$008e,$2c81,$0090,$2cc1		;VISIBLE AREA
						
Planes
	dc.w	$00e0
Bpl0pth	dc.w	$0000,$00e2
Bpl0ptl	dc.w	$0000,$00e4
Bpl1pth	dc.w	$0000,$00e6
Bpl1ptl	dc.w	$0000,$00e8
Bpl2pth	dc.w	$0000,$00ea
Bpl2ptl	dc.w	$0000,$00ec
Bpl3pth	dc.w	$0000,$00ee
Bpl3ptl	dc.w	$0000,$00f0
Bpl4pth	dc.w	$0000,$00f2
Bpl4ptl	dc.w	$0000,$00f4
Bpl5pth	dc.w	$0000,$00f6
Bpl5ptl	dc.w	$0000

Sprites						;SPRITES
	dc.w	$0120
Spl0pth	dc.w	$0000,$0122
Spl0ptl	dc.w	$0000,$0124
Spl1pth	dc.w	$0000,$0126
Spl1ptl	dc.w	$0000
	dc.w	$0128,$0000,$012a,$0000
	dc.w	$012c,$0000,$012e,$0000
	dc.w	$0130,$0000,$0132,$0000
	dc.w	$0134,$0000,$0136,$0000
	dc.w	$0138,$0000,$013a,$0000
	dc.w	$013c,$0000,$013e,$0000

	dc.w	$0180,$0332,$0182,$0055,$0184,$0543,$0186,$0ff2
	dc.w	$0188,$0ff2,$018a,$0de9,$018c,$0bc6,$018e,$09a4

	dc.w	$0190,$000f,$0192,$028f		;COLORS PLAY 2
	dc.w	$0194,$08f4,$0196,$0095
	dc.w	$0198,$0243,$019a,$00ff
	dc.w	$019c,$0ff0,$019e,$0fa0

	dc.w	$01a0,$0000,$01a2,$0fff		;SPRITE COLORS
	dc.w	$01a4,$0f00,$01a6,$0b00
	dc.w	$01a8,$0600,$01aa,$0F40
	dc.w	$01ac,$0F80,$01ae,$0Fa0
	dc.w	$01b0,$0Ff0,$01b2,$000f
	dc.w	$01b4,$004f,$01b6,$008f
	dc.w	$01b8,$00ff,$01ba,$00f0
	dc.w	$01bc,$0283,$01be,$0f0f

	dc.w	$ffdf,$fffe			; Pal enable

	dc.w	$ffff,$fffe			;END OF COPPERLIST
***********  Codes used  **************
Absolute	equ	$eee0		* Pixel co-ordinates
Relative	equ	$eee1		* offset from present co-ordinate
CoorLoop	equ	$eee2		* start of loop 
LoopBack	equ	$eee3		* end of loop
ChangeSpeed	equ	$eee4		* speed
End		equ	$eeee		* end marker

MapX
	dc.w	Absolute,280,060
	dc.w	CoorLoop,2
	dc.w	Relative
	dc.w	-6,0,-6,0,-6,0,-6,0,-6,0,-6,0		;Left
	dc.w	LoopBack		
	dc.w	0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0,6	; Down
	dc.w	CoorLoop,6
	dc.w	6,0,6,0,6,0,6,0,6,0,6,0,6,0,6,0		; Right
	dc.w	LoopBack		
	dc.w	Absolute,280,120
	dc.w	ChangeSpeed,$0000,$bbbb
	dc.w	CoorLoop,2
	dc.w	Relative
	dc.w	-4,00,-4,00,-4,00,-4,00,-4,00
	dc.w	-4,00,-4,00,-4,00,-4,00,-4,00
	dc.w	00,-4,00,-4,00,-4,00,-4,00,-4,00,-4,00,-4
	dc.w	00,-4,00,-4,00,-4,00,-4,00,-4,00,-4,00,-4
	dc.w	-4,00,-4,00,-4,00,-4,00,-4,00
	dc.w	-4,00,-4,00,-4,00,-4,00,-4,00
	dc.w	00,04,00,04,00,04,00,04,00,04,00,04,00,04
	dc.w	00,04,00,04,00,04,00,04,00,04,00,04,00,04

	dc.w	LoopBack
	dc.w	ChangeSpeed,$0000,$5555
	dc.w	Absolute,240,70
	dc.w	CoorLoop,2,Relative
	dc.w	3,0,3,0,3,0,3,0,3,0,3,0,3,0
	dc.w	3,0,3,0,3,0,3,0,3,0,3,0,3,0
	dc.w	0,3,0,3,0,3,0,3,0,3,0,3,0,3
	dc.w	0,3,0,3,0,3,0,3,0,3,0,3,0,3
	dc.w	3,0,3,0,3,0,3,0,3,0,3,0,3,0
	dc.w	3,0,3,0,3,0,3,0,3,0,3,0,3,0
	dc.w	0,-3,0,-3,0,-3,0,-3,0,-3,0,-3,0,-3
	dc.w	0,-3,0,-3,0,-3,0,-3,0,-3,0,-3,0,-3
	dc.w	LoopBack
	dc.w	ChangeSpeed,$0000,$ffff
	dc.w	End				; end marker

	DC.L	0,0,0,0,0,0
Triangle
	dc.w	$2,2,2,2,2,2,-2,0,-2,0,-2,0,2,-2,2,-2,2,-2
MapY
	dc.w	$0
LastX1	dc.w	240
LastY1	dc.w	60
LastX2	dc.w	240
LastY2	dc.w	60
CurrentX1	dc.w	240
CurrentY1	dc.w	60

Mask
; 		dcb.b	BobSize*BobDepth,$ff	; to see size of bob
		incbin	Jelly.mask
Bob
; 		dcb.b	BobSize*BobDepth,$ff	; to see size of bob
		incbin	Jelly.raw
Buffer1
		dcb.b	BobSize*BobDepth,$00
Buffer2
		dcb.b	BobSize*BobDepth,$00
Foreground
		dcb.b	ScreenSize*Depth,$00
Foreground_2
		dcb.b	ScreenSize*Depth,$00
Graphics	
		incbin	Foreground.raw


