	.include	'jaguar.s'
	.include	'blit.inc'
	.extern	VideoIni

	time equ 1
	testobject equ $14000	;this is just a llama
	sines equ $15000	;a sine table
	p_sines equ $15100
	ptab equ GPU_RAM+$800
	gpu_sem EQU $14FF0
	screen1 equ $18000	;a 16bit screen 320x200
	screen2 equ $38000	;same again
	screen3 equ $58000	;going to put the girl here
	rmw_obj equ $78000
	xmax equ 320-160		;limits for the
	ymax equ 200-50		;bouncing thangs
	in_buf equ GPU_RAM+$f60
	ud1 equ $78000
	ud2 equ $7c000
	TOP equ 26		;top of screen in halflines
	RobotBase equ $38000

.text

	move.w	MEMCON1,d0	;start up DRAM
	or.w	#$60,d0
	move.w	d0,MEMCON1

	move.l #stack,a7
	move.l #-1,ptab


	jsr VideoIni
	move #0,BG
	bsr GetGpuCode		;copy the GPU code to GPU RAM.
	move.b #1,gpu_data	;parameter to pass to GPU
	clr screen_ready
	move.l #$700000,rot_scale
	move.l #-1,gpu_sem	;GPU idle semaphore
				;set to 1 so the GPU can't run
				;while the blitter draws the test
				;pattern with the 68K


;	bsr cleanup
	lea sines,a0
	lea p_sines,a1		;make a positive-only sine table
	move #255,d0		;for use by the gpu
mpstab:	move.b (a0)+,d1
	ext d1
	add #$80,d1
	move.b d1,(a1)+
	dbra d0,mpstab
	bsr CalcPS

;	move.l #$807f807f,d0
;	lea rmw_obj,a0
;	move #319,d7
;makermw: move.l d0,(a0)+
;	dbra d7,makermw

	lea pong1,a0		;copy a test object to phrase aligned ram
	move.l #$14000,d0
	move.l d0,a1
	move #95,d0
copyobj: move.l (a0)+,(a1)+	;copy object to phrase aligned buffer
	dbra d0,copyobj
	clr.l (a1)+
	clr.l (a1)+

	move.l a1,midobj
	move #87,d0
cobj1:	move.l (a0)+,(a1)+
	dbra d0,cobj1
	


	bsr InitLists
	move.l dlist,d0		;put a list on the OLP
	move.w #0,ODP
	swap d0
	move.l d0,OLP		;activate the list

	bsr InitBeasties	;some stuff to move about
	move.l #cro_x,od_type
 
;	move.l	#Frame,104	;Initialise level 2 interrupt
	move.l #IServ,104
	move.w	#21,VI
	move #$0101,imsk
	move.w	#1,INT1		;enable frame and StopObject enable
	move.w	sr,d0
	and.w	#$f8ff,d0
	move.w	d0,sr




	move #-1,db_on

	move.w	#$C1,VMODE		; Turn on the display
	move.l #$78000,gscreen
	move #2,scaleshift
	bsr whiteclut
;	bra demo2		;this branch goes to robots
;	bra br			;this branch goes to static image display
	move #0,frames		;Pong for 7 secs
	bsr wd
	bsr colourclut
	move #0,frames		;s.Pong for 4 secs
	bsr wd


	lea beasties,a0
	move #160+24,d0
	move #-200,d1
	move.l #$18000,d2
	bsr makeit
	move #232+TOP,d0
	move.l #0,d1
	clr.l d2
	bsr setdampedbounce


	move #0,frames		;3 secs between drops
	bsr wd
	lea beasties+64,a0
	move #160+24,d0
	move #-200,d1
	move.l #$38000,d2
	bsr makeit
	move #232+TOP,d0
	move.l #0,d1
	clr.l d2
	bsr setdampedbounce
	move #180,frames
	bsr wd
	lea beasties+128,a0
	move #160+24,d0
	move #-200,d1
	move.l #$58000,d2
	bsr makeit
	move #232+TOP,d0
	move.l #0,d1
	clr.l d2
	bsr setdampedbounce
	move #600,frames
	bsr wd


	move #700,d0
	move.l #$10000,d1
	move.l #-$30000,d2
	bsr setvfall
	move #60,frames
	bsr wd

	lea beasties+64,a0
	move.l #-$10000,d1
	bsr setvfall
	move #60,frames
	bsr wd

	lea beasties,a0
	clr.l d1
	bsr setvfall
	move #0,frames	;3 secs for all images to clear
	bsr wd

	bsr wsync

	move.l #$18000,d2
	move #-160+TOP,d1
vband:	move #0,d0
sband:	bsr makeit
	move.l #-$40000,24(a0)  
	move #-155,20(a0)
	move #775,22(a0)
	move #5,12(a0)
	bsr nxtpic
	add #310,d0
	cmp #640,d0
	ble sband
	move.l a0,-(a7)
	bsr nxtpic
	move.l (a7)+,a0
	add #402,d1
	cmp #800,d1
	blt vband
	move #300,frames
	bsr wd
	bsr wsync

	move #8,d7
	lea beasties,a0
sspd:	move.l #$40000,28(a0)
	move #TOP-200,32(a0)
	move #TOP+1006,34(a0)
	move #6,12(a0)
	lea 64(a0),a0
	dbra d7,sspd

	move #300,frames
	bsr wd
	move #0,pong_on

 	bsr siney
; 	bsr siney
	lea beasties,a0
	move #8,d6
	move #$10,d5
	move #255,d7
sthflip: move d5,44(a0)
	move #4,38(a0)
	add #$10,d5
	movem.l d5-d6/a0,-(a7)
	move d7,d6
	bsr psiney		;1 sec per scale increment
	move d6,d7
	movem.l (a7)+,d5-d6/a0
	lea 64(a0),a0
	dbra d6,sthflip
	move d7,d6		;one more second to see them
	bsr psiney	

	bsr wsync
	bsr InitBeasties
	move #2,scaleshift
	move #160,pointx
	move #100,pointy
	bsr wsync
	lea beasties,a0
	move.l #$18000,d2
	move #160+24,d0
	move #TOP+240,d1
	bsr makeit

	clr 44(a0)
	move #2,38(a0)
	move #3,40(a0)

	move #200,frames
	bsr wd
	lea beasties+64,a0
	move.l #$38000,d2
	move #160+24,d0
	move #TOP+140,d1
	bsr makeit

	clr 44(a0)
	move #4,38(a0)
	move #2,40(a0)

	move #432+TOP,d0
	move.l #$20000,d1
	clr.l d2
	bsr setbounce

	move #0,frames	; just over 3 secs
	bsr wd

        lea beasties+128,a0
	move.l #$58000,d2
	move #160+24,d0
	move #TOP+140,d1
	bsr makeit

	clr 44(a0)
	move #6,38(a0)
	move #5,40(a0)

	move #432+TOP,d0
	move.l #-$20000,d1
	clr.l d2
	bsr setbounce

	move #200,frames
	bsr wd

	move #-1,beasties+76
	move #-1,beasties+140
	lea beasties,a0
	clr 40(a0)
	move #$20,10(a0)
	lea beasties+64,a0
	clr 40(a0)
	move #$20,10(a0)

	move #0,pong_on
;	move #2,scaleshift
	lea beasties,a0
	move #1,sptra
	move #1,sptrs
	move #$105,imsk
	move #76,frames
	bsr wd
	move #3,sptra
	move #2,sptrs
	move #76,frames
	bsr wd
	move #1,sptra
	move #3,sptrs
	move #76,frames
	bsr wd
	move #4,sptra
	move #2,sptrs
	move #76,frames
	bsr wd
	move #1,sptrs
	move #76,frames
	bsr wd
	move #$101,imsk
	move.l #IOff,104
	bsr wsync
	move.l #IServ2,104
	move #$105,imsk
	move #76,frames
	bsr wd



	lea beasties+64,a0
	move.l #$38000,d2
	move #3,d6
	move #160+24,d0
	move #TOP+240,d1
	bsr makeit
	move #2,38(a0)
	clr 44(a0)
;	move #1,40(a0)	

	move #76,frames
	bsr wd

	bsr wsync
	bsr InitBeasties

	bsr CalcPS2
	bsr wsync
	lea beasties,a0
	move.l #$38000,d2
	move #3,d6
	move #160+24,d0
	move #TOP+240,d1
	bsr makeit
	move.l #IServ3,104
	move #76,frames
	bsr wd
skip:	bsr InitBeasties
	move #1,pong_on
	move #1,scaleshift
	move #$101,imsk
	move.l #IOff,104
	move #240,frames
	bsr wd

	move #0,pong_on

	lea beasties,a0
	move.l gscreen,d2
	move #160+24,d0
	move #TOP+240,d1
	bsr make160	
	move #$40,10(a0)
	lea beasties+64,a0
	move.l gscreen,d2
	move #160+24,d0
	move #TOP+240,d1
	bsr make160	
	move #$c0,8(a0)

	bsr wsync
	move.l #0,rot_scale_grav
	move #69,mainloop_count
	move.l #rotate1,mainloop_routine
	clr.l gpu_sem
	bsr mainloop

	move.l #$100,rot_scale_grav
	move #69,mainloop_count
	bsr mainloop

	lea beasties+64,a0
	move #4,38(A0)
	clr 44(a0)
	move #6,40(a0)

	move #332+TOP,d0
	move.l #-$20000,d1
	clr.l d2
	bsr setbounce


	lea beasties+128,a0
	move.l gscreen,d2
	move #160+24,d0
	move #TOP+180,d1
	bsr make160	
	move #2,38(A0)
	clr 44(a0)
	move #1,40(a0)

	move #432+TOP,d0
	move.l #-$10000,d1
	clr.l d2
	bsr setbounce


	lea beasties+192,a0
	move.l gscreen,d2
	move #160+100,d0
	move #TOP+240,d1
	bsr make160	
	move #6,38(A0)
	clr 44(a0)
	move #4,40(a0)

	move #432+TOP,d0
	move.l #-$20000,d1
	clr.l d2
	bsr setbounce

	move.l #$400,rot_scale_grav
	move #69,mainloop_count
	bsr mainloop

	move #-1,beasties+76
	move #-1,beasties+140
	move #-1,beasties+204

	move #80,d4
	move #50,d5
	bsr initrotators
	move.l #multirotate,mainloop_routine
	move #69,mainloop_count
	move #3,d7
	bsr mainloop

	move #3,beasties+76
	move #3,beasties+140
	move #3,beasties+204
	move #69,mainloop_count
	bsr mainloop

	move #-1,beasties+76
	move #-1,beasties+140
	move #-1,beasties+204


	move #40,d4
	move #25,d5
	bsr initrotators
	move.l #multirotate,mainloop_routine
	move #69,mainloop_count
	move #15,d7
	bsr mainloop

	move #3,beasties+76
	move #3,beasties+140
	move #3,beasties+204
	move #69,mainloop_count
	bsr mainloop

	move #-1,beasties+76
	move #-1,beasties+140
	move #-1,beasties+204

	move.l #$78000,gscreen
	move.l #0,GPU_RAM+$fc4
	move #1,scaleshift
	lea beasties,a0
	move.l gscreen,d2
	move #160+24,d0
	move #TOP+240,d1
	bsr make160	
	move #$40,10(a0)
	lea beasties+64,a0
	move.l gscreen,d2
	move #160+24,d0
	move #TOP+240,d1
	bsr make160	
	move #$5f,8(a0)
	move #$30,10(a0)
	clr.l gpu_sem

	lea beasties+128,a0
	move.l gscreen,d2
	move #160+24,d0
	move #TOP+240,d1
	bsr make160	
	move #$3f,8(a0)
	clr.l gpu_sem

	move #0,p2inc
	move #$20,pointer2
	move.l #$400000,rot_scale
	move.l #$200,rot_scale_grav
	clr.l rot_scale_add
	move.l #protate,mainloop_routine
	move #69,mainloop_count
	bsr mainloop

	move #1,p2inc
	move #69,mainloop_count
	bsr mainloop

	move #80,d4
	move #50,d5
	bsr initrotators
	move.l #multiprotate,mainloop_routine
	move #69,mainloop_count
	move #3,d7
	bsr mainloop

	move #40,d4
	move #25,d5
	bsr initrotators
	move.l #multiprotate,mainloop_routine
	move #69,mainloop_count
	move #15,d7
	bsr mainloop

	lea beasties+64,a0
	move #2,38(A0)
	clr 44(a0)
	lea beasties+128,a0
	move #4,38(A0)
	clr 44(a0)
	move #69,mainloop_count
	bsr mainloop

	move.l #0,GPU_RAM+$fc0
	move.l #$00000080,GPU_RAM+$fbc
	move #1,p2inc
	lea beasties+64,a0
	move #0,38(A0)
	move #$5f,8(a0)
	lea beasties+128,a0
	move #0,38(A0)
	move #$3f,8(a0)
	move.l #$18000,grad_source
	move.l #gradient1,mainloop_routine
	move #3,g1i
	move #3,g2i
	move #300,mainloop_count
	bsr mainloop

	move.l #gradient2,mainloop_routine
	move.l #$78000,cscreen
	move.l #$58000,dscreen
	lea beasties+192,a0
	move.l gscreen,d2
	move #160+24,d0
	move #TOP+240,d1
	bsr make160	
	move #$1f,8(a0)
	move #$10,10(a0)
	move #1,g1i
	move #6,g2i
	move #1,gpui
	move #3,db_on
	move.l #$38000,grad_source
	move #300,mainloop_count
	bsr mainloop
	lea beasties,a0
	move #2,38(A0)
	clr 44(a0)
	lea beasties+64,a0
	move #2,38(A0)
	move #$40,44(a0)
	lea beasties+128,a0
	move #2,38(A0)
	move #$80,44(a0)
	lea beasties+192,a0
	move #2,38(A0)
	move #$c0,44(a0)
	move #300,mainloop_count
	bsr mainloop

	move.l #$38000,grad_source
	move #7,g1i
	lea beasties+64,a0
	move #432+TOP,d0
	move.l #0000,d1
	clr.l d2
	bsr setbounce
	lea beasties+128,a0
	move #432+TOP,d0
	move.l #0000,d1
	clr.l d2
	bsr setbounce
	move.l #-$20000,28(A0)
	lea beasties+192,a0
	move #432+TOP,d0
	move.l #0000,d1
	clr.l d2
	bsr setbounce
	move.l #-$40000,28(A0)
	move #1,g1i
	move #2,g2i
	move #300,mainloop_count
	bsr mainloop
	lea beasties,a0
	move #16+80,d0
	move #TOP+120,d1
	bsr stopem

	lea beasties+64,a0
	move #16+240,d0
	move #TOP+120,d1
	bsr stopem
	lea beasties+128,a0
	move #16+80,d0
	move #TOP+320,d1
	bsr stopem
	lea beasties+192,a0
	move #16+240,d0
	move #TOP+320,d1
	bsr stopem

	move #-1,g1i
	clr g2i
	move #-2,gpui
	move #$600,grad
	move #$180,grad2
	move.l #$2000000,d0
	move.l d0,GPU_RAM+$fc0
	move.l #150,GPU_RAM+$fbc
	move #100,mainloop_count
	bsr mainloop
	move.l #-5,g1i
	move #100,mainloop_count
	bsr mainloop
	move.l #3,g2i
	move #100,mainloop_count
	bsr mainloop

go:	move #-1,db_on
	move #200,gpu_data
	bsr InitBeasties
	move #2,scaleshift
	move.l #$38000,cscreen
	move.l #$58000,dscreen
	move.l #gradient3,mainloop_routine
	lea beasties,a0
	move #160+24,d0
	move #232+TOP,d1
	move.l #$18000,d2
	bsr makeit
	move #0,db_on
	move.l #$18000,grad_source	
	move #0,gpui
	move.l #0,GPU_RAM+$fc0
	move #2,g2i
	move #1,g1i
	move #0,gpui
	move.l #$30000,sws1
	move.l #$40000,sws2
	move #150,mainloop_count
	bsr mainloop
	move.l #gradient4,mainloop_routine
	move #$10,p1a
	move #$014,p2a
 	move #150,mainloop_count
	bsr mainloop
	move #1,gpui
	move #$50,p1a
	move.l #$70000,sws2
llama: 	move #150,mainloop_count
	bsr mainloop
;	bra llama		;loop forever warping if left in
	move #0,yi
	move #1,yia
	move.l #gradient5,mainloop_routine
	move.l #$10000,sws2
	move #$100,p2a
	move #300,mainloop_count
	bsr mainloop
	move #2,gpui
	lea beasties+64,a0
	move.l gscreen,d2
	move #160+24,d0
	move #TOP+240,d1
	bsr makeit	
	move #$cf,8(a0)
	move #$18,10(a0)
	lea beasties+128,a0
	move.l gscreen,d2
	move #160+24,d0
	move #TOP+240,d1
	bsr makeit	
	move #$1f,8(a0)
	move #$10,10(a0)
	move #2,db_on

	move #$8303,p1c
	move #$8504,p2c
	move #$00,p2a
	move #$00,p1a
	move #1,yia
 	move #150,mainloop_count
	bsr mainloop

	lea beasties+64,a0
	move #2,38(A0)
	move #$40,44(a0)
	lea beasties+128,a0
	move #2,38(A0)
	move #$80,44(a0)
	move #300,mainloop_count
	bsr mainloop

	lea beasties+64,a0
	move #0,38(A0)
	move #$5f,8(a0)
	lea beasties+128,a0
	move #0,38(A0)
	move #$3f,8(a0)	


	bsr clear23
	move.l #-1,ud1
	move.l #-1,ud2
	move.l #lines1,mainloop_routine
 	move #1000,mainloop_count
	bsr mainloop

	lea beasties+64,a0
	move #2,38(A0)
	move #$40,44(a0)
	lea beasties+128,a0
	move #2,38(A0)
	move #$80,44(a0)
	move #300,mainloop_count
	bsr mainloop


	lea beasties+64,a0
	move #1,40(A0)
	lea beasties+128,a0
	move #2,40(A0)
camel:	move #300,mainloop_count
	bsr mainloop


	jmp camel

demo2: move #0,pong_on
	move #1,scaleshift
	move.l #$18000,d2
	move #232+TOP,d1
	move #0,d0
	move #1,d6
	lea beasties,a0
sband2: bsr wsync
	bsr makeit
	move #$4a,8(a0)
	move #$24,10(a0)
	btst #0,d6
	beq sband21
	move #$b6,8(a0)
sband21:	move.l #-$40000,24(a0)  
	move #-190,20(a0)
	move #550,22(a0)
	move #5,12(a0)
	lea 64(a0),a0
	add #367,d0
	dbra d6,sband2
	lea beasties+128,a0
	move.l #$30000,d2
	move #160+24,d0
	move #TOP+240,d1
	bsr makerobot	
	move #$3f,8(a0)
	move #$20,10(a0)
	lea beasties+192,a0
	move #0,d3		;orbital phase
	move.l #$4000,d4
cow:	move.l #$30000,d2
	move #160+24,d0
	move #TOP+240,d1
	bsr makerobot	
	move #$3f,8(a0)
	move #$20,10(a0)
	move #8,12(a0)
	move d3,48(a0)
	move.l d4,50(a0)
	lea 64(a0),a0
	add #$20,d3
	add.l #$2000,d4
	cmp #$100,d3
	blt cow

goaty:	move #500,frames
	bsr wd
	bra goaty

br:	move #0,pong_on
	lea beasties,a0
	move #160+24,d0
	move #232+TOP,d1
	move.l #$18000,d2
	bsr makeit
goaty3: bra goaty3
	move #0,p2inc
	move #$20,pointer2
	move.l #$400000,rot_scale
	move.l #$200,rot_scale_grav
	clr.l rot_scale_add
	move #-1,db_on
	move.l #$38000,cscreen
	move.l #$58000,dscreen
	move.l #bigprotate,mainloop_routine
	move #0,db_on
	move.l #0,GPU_RAM+$fc0
	clr.l gpu_sem
	move #1000,mainloop_count
	bsr mainloop
	move #1,p2inc
goaty2:	move #1000,mainloop_count
	bsr mainloop
	bra goaty2

stopem:	clr 38(a0)
	move #$3f,8(a0)
	move #$20,10(a0)
 	move d0,(a0)
	move d1,4(a0)
	clr 12(a0)
	rts


cleanup: lea $37400,a0
	move #$24f,d0
cup1:	clr.l (a0)+
	dbra d0,cup1
 lea $57400,a0
	move #$17f,d0
cup2:	clr.l (a0)+
	dbra d0,cup2
 lea $77400,a0
cup3: move.l #0,(a0)+
	cmp.l #$80000,a0
	bne cup3
	rts



initrotators: lea rotators,a0
	clr d6
	clr d7
	clr d0
irotat:	move d0,(a0)+
	move d0,d1
	add #1,d1
	move d1,d2
	btst #0,d0
	bne irot1
	neg d2
irot1:	move d2,(a0)+
	asl #8,d1
	clr.l d2
	move d1,d2
	swap d1
	asr.l #4,d1	
	move.l #$700000,(a0)+
	move.l d2,(a0)+	
	move.l #0,(A0)+
	move d6,(a0)+
	move d7,(a0)+
	move d4,(a0)+
	move d5,(a0)+
	lea 8(a0),a0
	add #1,d0
	add d4,d6
	cmp #160,d6
	blt irotat
	move #0,d6
	add d5,d7
	cmp #100,d7
	blt irotat
	
	rts

psiney: move #60,d7
psinespd: move #8,d3
	lea beasties,a0
	move d7,-(a7)
	bsr wsync
	move (a7)+,d7
psinesp: move d6,d5
	and #$ff,d5
	move.b 0(a1,d5.w),d4
	ext d4
	swap d4
	clr d4
	asr.l #4,d4
	move.l d4,24(a0)
	add.b #$40,d5
	move.b 0(a1,d5.w),d4
	ext d4
	swap d4
	clr d4
	asr.l #4,d4
	move.l d4,28(a0)
	lea 64(a0),a0
;	lea 64(a0),a0
	dbra d3,psinesp
	sub #1,d6
	dbra d7,psinespd
	rts

siney:	lea sines,a1
	move #256,d6
sinespd: move #8,d3
	lea beasties,a0
	bsr wsync
sinesp:	move d6,d5
	and #$ff,d5
	move.b 0(a1,d5.w),d4
	ext d4
	swap d4
	clr d4
	asr.l #4,d4
	move.l d4,24(a0)
	add.b #$40,d5
	move.b 0(a1,d5.w),d4
	ext d4
	swap d4
	clr d4
	asr.l #4,d4
	move.l d4,28(a0)
	lea 64(a0),a0
;	lea 64(a0),a0
	dbra d3,sinesp
	dbra d6,sinespd
	rts

nxtpic:	lea 64(a0),a0
	add.l #$20000,d2
	cmp.l #$78000,d2
	bne rrts
	move.l #$18000,d2
	rts

wsync: move frames,d7
wsnc: 	cmp frames,d7
	beq wsnc
	rts

whiteclut: lea CLUT,a0
	move #15,d0
wclut: move.l #$88ff88ff,(a0)+
	dbra d0,wclut
	rts

colourclut: lea CLUT,a0
	move.l #$08ff08ff,(a0)+
	move.l #$08ff08ff,(a0)+
	move.l #$0fff0fff,(a0)+
	move.l #$0fff0fff,(a0)+
	move.l #$ffffffff,(a0)+
	move.l #$ffffffff,(a0)+
	move.l #$f8fff8ff,(a0)+
	move.l #$f8fff8ff,(a0)+
	move.l #$f0f0f0f0,(a0)+
	move.l #$f0f0f0f0,(a0)+
	move.l #$00ff00ff,(a0)+
	move.l #$00ff00ff,(a0)+
	rts

clearscreens:	lea screen1,a0
	clr d0			;Clear screen #1
	clr d1	
	move #320,d2
	move #200,d3
	move #$8000,d4
	bsr BlitBlock

clear23:	lea screen2,a0
	clr d0			;Clear screen #2
	clr d1	
	move #320,d2
	move #200,d3
	move #0,d4
	bsr BlitBlock

	lea screen3,a0
	clr d0			;Clear screen #3
	clr d1	
	move #320,d2
	move #200,d3
	move #0,d4
	bra BlitBlock


setbounce: move #0,20(a0)
	move #320,22(a0)
	move.l d1,24(a0)
	clr.l 28(a0)
	move.l #$1000,32(a0)
	move d0,36(a0)
	move #3,12(a0)		;make Y damped bounce+X linear
	rts

setdampedbounce: move #0,20(a0)
	move #320,22(a0)
	move.l d1,24(a0)
	move.l d2,28(a0)
	move.l #$3000,32(a0)
	move d0,36(a0)
	move #8,46(a0)
	move #1,12(a0)		;make Y damped bounce+X linear
	rts

setvfall: bsr setdampedbounce
	move #4,12(a0)
	rts

makerobot: move #2,14(a0)
	bsr mit
;	move #14,48(a0)
	move #6,48(a0)
	move #0,50(a0)
	move #0,52(a0)
	move #160,54(a0)
	move #450,56(a0)
	move.l #0,60(a0)
	move #7,12(a0)
	rts
	
make160: move #1,14(a0)
	bra mit

makeit:	move #0,14(a0)
mit:	move d0,(a0)
	move d1,4(a0)
 	move #$7f,8(a0)
	move 8(a0),44(a0)
	move #$20,10(a0)
	move.l d2,16(a0)
	move #0,40(a0)		;vscale rate
	move #$ff,42(a0)	;vscale ptr
	clr 38(a0)		;zero speed
	move #0,12(a0)		; make an Object
	rts

wd: tst frames
 bpl wd
 rts

;	bsr TestPattern		;Blitter test pattern to screen1
;	bsr GetGirl		;get CRY piccie of a girl
;	bsr LeonardsMandy
;	move.l #0,gpu_sem	;allow the GPU to start up

;
; This loop runs the GPU/Blitter code.  I found that if you
; started up the GPU/Blitter pair from inside the FRAME
; Interrupt, the system would fall over if they got really heavily
; loaded.  MAINLOOP just waits for a sync from the FRAME routine,
; launches the GPU, then loops waiting for another sync.


mainloop: add #$2011,counter
;	move counter,BORD1
 	tst sync
	bne mainloop
	move #1,sync
	move.l mainloop_routine,a0
	jsr (a0)
;	tst mainloop_count
	sub #time,mainloop_count
	bpl mainloop
	rts
	

;	bra wibble
	illegal				;drop out to de old bugger


gradient1: bsr gradstuff
	move.l grad_source,d0
	swap d0
	move.l d0,GPU_RAM+$fc8
	move.l #3,d0
	swap d0
	move.l d0,GPU_RAM+$ffc
	bra gpu_run


gradient5: move yi,d0
	add yia,d0
	move d0,yi
	and #$fff,d0
	sub #$7fe,d0
	bpl grd5
	neg d0
grd5:	ext.l d0
	swap d0
	move.l d0,GPU_RAM+$fc0


gradient4: move p1a,d0
	add p1c,d0
	move d0,p1c
	and.l #$ffff,d0
	sub.l #$8000,d0
	bpl g41
	neg.l d0
g41:
;	asl.l #5,d0
	swap d0
	move.l d0,GPU_RAM+$fe8
 	move p2a,d0
	add p2c,d0
	move d0,p2c
	and.l #$ffff,d0
	sub.l #$8000,d0
	bpl g42
	neg.l d0
g42:
;	asl.l #5,d0
	swap d0
	move.l d0,GPU_RAM+$fe4
	bra grd



lines1: bsr pat_stuff
	move.l #0,GPU_RAM+$ffc
	bra gpu_run_b

gradient3: move.l #1,GPU_RAM+$fe8
	move.l #$2,GPU_RAM+$fe4
grd: 	move.l #310,GPU_RAM+$fbc
	bsr sinestuff
	move.l #5,d1
	bsr zzz
	bra gpu_run_b

gradient2: bsr gradstuff
	move.l #3,d1
	bsr zzz
	move.l dscreen,a0
	move #0,d0
	bsr cls160
	bra gpu_run_b

zzz:	move.l grad_source,d0
	bne gradi2
	move.b gpu_data,d2
	and #$07,d2
	bne gradfb
	move.l #$18000,d0
	bra gradi2
gradfb:	addq.l #1,d1
	move.l cscreen,d0
gradi2:	swap d0
	move.l d0,GPU_RAM+$fc8
	swap d1
	move.l d1,GPU_RAM+$ffc
	rts


rotate1: move #160,d0
	swap d0
	move #100,d0
	move.l d0,GPU_RAM+$fd0
	clr.l d0
	move.l d0,GPU_RAM+$fcc
	move.l #$38000,d0
	swap d0	
	move.l d0,GPU_RAM+$fc8
	bsr f_rotatestuff
	bra gpu_run

protate2: move cpc,d0
	and #$ff,d0
	sub #$80,d0
prot2:	ext.l d0
	swap d0
	move.l d0,GPU_RAM+$fc4
	bra protate
	
bigprotate: move #320,d0
	swap d0
	move #100,d0
	move.l d0,GPU_RAM+$fd0
	clr.l d0
	move.l d0,GPU_RAM+$fcc
	move.l #$18000,d0
	bsr gnu
	bsr bigfp
	bra gpu_run_b

protate: move #160,d0
	swap d0
	move #100,d0
	move.l d0,GPU_RAM+$fd0
	clr.l d0
	move.l d0,GPU_RAM+$fcc
	move.l #$38000,d0
	bsr gnu
prota1: bsr fp_rotatestuff
	bra gpu_run

gnu:	swap d0	
	move.l d0,GPU_RAM+$fc8
	move #100,cpy			;for GG pic
	sub #1,cpc
 	move cpc,d0
	and #511,d0
	sub #256,d0
	bpl por81
	neg d0
por81:	add #32,d0
	move d0,cpx
	rts

multiprotate:	lea rotators,a5
	sub #1,cpc
 	move cpc,d0
	and #511,d0
	sub #256,d0
	bpl por82
	neg d0
por82:	add #32,d0
	move d0,cpx
	lea picstarts,a6
	move d7,d6
mpr: 	move 16(a5),d0
	swap d0
	move 18(a5),d0
	move.l d0,GPU_RAM+$fcc
	move 20(a5),d0
	swap d0
	move 22(a5),d0
	move.l d0,GPU_RAM+$fd0
	move.l (a6)+,d0
	bpl mpr_1
	move.l #picstarts,a6
	move.l (a6)+,d0
mpr_1:	swap d0	
	move.l d0,GPU_RAM+$fc8
	move (a5)+,pointer2
	move (a5)+,p2inc
	move.l (a5)+,rot_scale
	move.l (a5)+,rot_scale_grav
	move.l (a5)+,rot_scale_add
	movem.l d6-d7/a5-a6,-(a7)	
	move gpu_data,-(a7)
	bsr fp_rotatestuff
	move (a7)+,gpu_data
	bsr gpu_run
	movem.l (a7)+,d6-d7/a5-a6
	move.l rot_scale_add,-(a5)
	move.l rot_scale_grav,-(a5)
	move.l rot_scale,-(a5)
	move p2inc,-(A5)
	move pointer2,-(a5)
	lea 32(a5),a5
	dbra d6,mpr
	add.b #1,gpu_data
	rts

multirotate: lea rotators,a5
	lea picstarts,a6
	move d7,d6
mr: 	move 16(a5),d0
	swap d0
	move 18(a5),d0
	move.l d0,GPU_RAM+$fcc
	move 20(a5),d0
	swap d0
	move 22(a5),d0
	move.l d0,GPU_RAM+$fd0
	move.l (a6)+,d0
	bpl mr_1
	move.l #picstarts,a6
	move.l (a6)+,d0
mr_1:	swap d0	
	move.l d0,GPU_RAM+$fc8
	move (a5)+,pointer2
	move (a5)+,p2inc
	move.l (a5)+,rot_scale
	move.l (a5)+,rot_scale_grav
	move.l (a5)+,rot_scale_add
	movem.l d6-d7/a5-a6,-(a7)	
	bsr f_rotatestuff
	bsr gpu_run
	movem.l (a7)+,d6-d7/a5-a6
	move.l rot_scale_add,-(a5)
	move.l rot_scale_grav,-(a5)
	move.l rot_scale,-(a5)
	move p2inc,-(A5)
	move pointer2,-(a5)
	lea 32(a5),a5
	dbra d6,mr
	rts
	



picstarts: dc.l $18000,$38000,$58000,-1




Wibble:
;
; do wibbly screen thang

	move #0,d0
	move #0,d1
	move #320,d2
	move #200,d3
	move #0,d4
	move #0,d5
	lea screen1,a0
	lea screen2,a1
funkloop:	bsr Funky
	add.l #10,yinc_a
	and.l #$1ff,yinc_a
	add.l #9,xinc_a
	and.l #$1ff,xinc_a
	add.l #8,xinc_a2
	and.l #$1ff,xinc_a2
	bra funkloop

TestPattern:	lea screen1,a0
	clr d0			;Test blitter block draw
	clr d1	
	move #320,d2
	move #200,d3
	move #$ffff,d4
bb_loop: bsr BlitBlock
	sub #$0101,d4
	addq #1,d0
	addq #1,d1
	subq #2,d2
	subq #2,d3
	bne bb_loop

	move #160,d0
	move #100,d1		;do blitter draw line
	move #0,d2
	move #0,d3
	move #$ff80,d4
tbl:	bsr BlitLine
	add.b #2,d4
	add #5,d2
	cmp #320,d2
	blt tbl

	move #320,d2
	move #0,d3
	move #$3f80,d4
tb2: 	bsr BlitLine
	add.b #2,d4
	add #5,d3
	cmp #200,d3
	blt tb2

	move #320,d2
	move #200,d3
	move #$7f80,d4
tb3: 	bsr BlitLine
	add.b #2,d4
	sub #5,d2
	bpl tb3

	move #0,d2
	move #200,d3
	move #$cf80,d4
tb4: 	bsr BlitLine
	add.b #2,d4
	sub #5,d3
	bpl tb4
	rts

CalcPS:	move #511,d1
	lea pstab,a0
	lea sines+256,a1
cps:	move d1,d2
	and #$ff,d2
	move.b 0(a1,d2.w),d0
	and #$ff,d0
	add #42,d0
	or #$c000,d0
	move d0,(a0)+
	add.b #$40,d2
	move.b 0(a1,d2.w),d0
	and #$ff,d0
	add #42,d0
	or #$c000,d0
	move d0,(a0)+
	dbra d1,cps
	rts



CalcPS2: move #511,d1
	lea pstab,a0
	lea sines+256,a1
cps2:	move d1,d2
	and #$ff,d2
	move.b 0(a1,d2.w),d0
	and #$ff,d0
	lsr #1,d0
;	add #42,d0
	or #$c000,d0
	move d0,(a0)+
	asl #3,d2
	and #$ff,d2
	move.b 0(a1,d2.w),d0
	and #$ff,d0
	lsr #3,d0
	add #$20,d0
	or #$2000,d0
	move d0,1022(a0)
	dbra d1,cps2
	rts




IServ3:  btst.b #2,INT1+1
	beq Frame3	;if not stopobj must be Frame
	movem.l d0/a0,-(a7)
	move.l psptr,a0
	move (a0)+,d0
	move.l a0,psptr
	swap d0
	move.l psptr2,a0
	move (a0)+,d0
	move.l a0,psptr2
	move.l elist,a0
	move d0,8(a0)
	swap d0
	move d0,(a0)
	movem.l (a7)+,d0/a0
	move #$405,INT1
	clr INT2
	rte


IServ2:  btst.b #2,INT1+1
	beq Frame2		;if not stopobj must be Frame
	move.l a0,-(a7)
	move.l psptr,a0
	move.l (a0)+,-(a7)
	move.l a0,psptr
	move.l elist,a0
	move (a7)+,(a0)
	move (a7)+,32(a0)
	move.l (a7)+,a0
	move #$405,INT1
	clr INT2
	rte


IServ:  btst.b #2,INT1+1
	beq Frame		;if not stopobj must be Frame
	movem.l d0/a0,-(a7)
	move sptrs,d0
	add d0,sptr
	move sptr,d0
	and #$ff,d0
	lea sines+256,a0
	move.b 0(a0,d0.w),d0
	add #42,d0
	move.l elist,a0
	and #$f000,(a0)
	or d0,(a0)
	movem.l (a7)+,d0/a0
	move #$405,INT1
	clr INT2
	rte

IOff: btst.b #2,INT1+1
	beq Frame
	move #$401,INT1
	clr INT2
	rte


Frame2:	movem.l d0-d7/a0-a6,-(a7)
	add #2,pscou
	move pscou,d0
	and #$ff,d0
	asl #2,d0
	lea pstab,a0
	lea 0(a0,d0.w),a0
	move.l a0,psptr
	bra fr

Frame3:	movem.l d0-d7/a0-a6,-(a7)
	add #2,pscou
	move pscou,d0
	and #$ff,d0
	asl #1,d0
	lea pstab,a0
	lea 0(a0,d0.w),a0
	move.l a0,psptr
	add #2,pscou2
	move pscou2,d0
	and #$ff,d0
	asl #1,d0
	lea pstab+1024,a0
	lea 0(a0,d0.w),a0
	move.l a0,psptr2
	bra fr

Frame:  move sptrr,sptr
 	movem.l d0-d7/a0-a6,-(a7)	;simple thang to make
	move sptra,d0
	add d0,sptrr

fr:	move #0,BORD1		;for a timing bar
	move #0,BORD2
	sub #time,frames
	tst screen_ready	;is GPU ready with a new screen
	beq no_new_screen	;no
	tst sync
	beq no_new_screen
	move.l cscreen,d1
	move.l dscreen,cscreen
 	move.l d1,dscreen	;swap screens
	clr screen_ready
	clr sync

no_new_screen:	move.l dlist,d0
	move.l d0,d1
	add.l #22,d1
	move.l d1,elist
	move.l d0,a0		;address of current DL
	move db_on,d7
	bmi no_db
setdb:		
	lea 8(a0),a0		;skip first object which is a cond.
	move.l cscreen,d6	;get address of current displayed screen
	and.l #$fffffff8,d6	;lose three LSB's
	move #9,d5		;shift counter
	lsl.l d5,d6		;move to correct bit position
	move.l (a0),d1		;get first word of the BMO
	and.l #$fff,d1		;clear data pointer
	or.l d6,d1		;mask in new pointer
	move.l d1,(a0)		;replace in OL
	lea 24(a0),a0		;skip to nxt object
	dbra d7,setdb		;loop for all DB backgrounds


no_db:	move.w #0,ODP
	swap d0
	move.l d0,OLP		;activate the display list

 	bsr RunBeasties		;build the next one

	move.l dlist,d0
 	move.l blist,dlist
	move.l d0,blist		;swap dlists
;	bsr run_rotate_vars	;wibble some things around 
;	bsr run_tf_vars
;	bsr run_pat_vars
; 	move #$FFFF,BORD1	;end of timing baa
 	movem.l (a7)+,d0-d7/a0-a6
;	sub #time,mainloop_count
	move.w	imsk,INT1	;do interrupt stuff
	move.w	#0,INT2
	rte

gpu_run_b: move.l dscreen,d0
	bra rgpu 


gpu_run:
;	move.l #0,gpu_sem
;	move #1,screen_ready
;	rts
	move.l gscreen,d0
rgpu: 	tst.l gpu_sem		;has GPU finished?
	bmi rgpu
	bsr WaitBlit	
	swap d0
	move.l d0,GPU_RAM+$fec
;	bsr gradstuff
;	bsr f_rotatestuff
;	bra tf_stuff
;	bsr pat_stuff
 	move.l #-1,gpu_sem	;flag GPU running
	move.l #$403000,d0	;start address of GPU program
	swap d0			;for GPU endian-ness
	move.l d0,GPU_PC	;set GPU's PC
	move.l #$11,d0		;GPU_GO is 1
	swap d0
	move.l d0,GPU_CTRL	;fire up GPU	
still_running: tst.l gpu_sem
	bmi still_running	;wait for GPU stop
	bsr WaitBlit		;wait for Blitter stop
	move #1,screen_ready	;tell int routine the screen is ready				;for display
 	rts 

run_pat_vars: add.l #$200,pointer
 add.l #$3,step1
 add.l #$2,step2
 add #$80,step3
 add #$5,step4
 add #$90,step5
 add #$4,step6
 rts

pat_stuff: bsr run_pat_vars
 	move.l pointer,d0
	and.l #$ffff,d0
 	swap d0
	move.l d0,in_buf
	move.l step1,d0
	and.l #$ffff,d0
	swap d0
	move.l d0,in_buf+4
	move.l step2,d0
	and.l #$ffff,d0
	swap d0
	move.l d0,in_buf+8	
	move step3,d0
	and.l #$ffff,d0
	swap d0
	move.l d0,in_buf+16	
	move step4,d0
	and.l #$ffff,d0
	swap d0
	move.l d0,in_buf+20	
	move step5,d0
	and.l #$ffff,d0
	swap d0
	move.l d0,in_buf+24	
	move step6,d0
	and.l #$ffff,d0
	swap d0
	move.l d0,in_buf+28	


;	move.l #$403600,d1
	move.l #ud1,d1
	eor #1,ud
	bne pstuff1
;	move.l #$403900,d1
	move.l #ud2,d1
pstuff1: swap d1
	move.l d1,in_buf+12
	rts


run_tf_vars: move.l tx_pos,d0
	move.l tx_vel,d1
	add.l d1,d0
	bpl tx_ok1
tx_bounce: neg.l d1
	add.l d1,d0
	bra tx_ok2
tx_ok1: cmp.l #$1200000,d0
	bge tx_bounce
tx_ok2: move.l d0,tx_pos
	move.l d1,tx_vel
 	move.l ty_pos,d0
	move.l ty_vel,d1
	add.l d1,d0
	bpl ty_ok1
ty_bounce: neg.l d1
	add.l d1,d0
	bra ty_ok2
ty_ok1: cmp.l #$a80000,d0
	bge ty_bounce
ty_ok2: move.l d0,ty_pos
	move.l d1,ty_vel
	rts
 	move tz_pos,d0
	move tz_vel,d1
	add d1,d0
	bpl tz_ok1
tz_bounce: neg d1
	add d1,d0
	bra tz_ok2
tz_ok1: cmp #$5f0,d0
	bge tz_bounce
tz_ok2: move d0,tz_pos
	move d1,tz_vel
	add #1,pointer
	move pointer,d0
	and #$ff,d0
	lea CLUT,a0
	lea sines,a1
	move #0,d1
	move #8,d3
spall: move d1,d2
	lsl d3,d2
 	move.b 0(a1,d0.w),d4
	ext d4
	add #$80,d4
	asr #1,d4
	add #$80,d4	
	or d4,d2
 	move d2,(a0)+
	add.b #1,d0
	add #1,d1
	cmp #256,d1
	blt spall
	rts
	

tf_stuff: clr d0
	move.l dscreen,a0
	bsr cls8		;remember changed to 8bit!
	move tz_pos,tzp
	move.l ty_pos,d1
	lsl.l #4,d1
	swap d1
	move d1,d0
	and #$0f,d1
 	asr #4,d0
	move.l tx_pos,d3
	lsl.l #4,d3
	swap d3
	move d3,d2
	asr #4,d2
;	asl #1,d2
	mulu #320,d0
	lea screen1,a0
	add.l d0,a0
	lea 0(a0,d2.w),a0
	move #$200,d6
	or d1,d6		;put in Z frac
	and #$0f,d3
	move d3,d1
	move #32,d3
gpix: 	move #26,d2		;X loop
	move.l a0,a1
	move #$d0,d7
	or d1,d7		;X frac
gpix2: 	move.b (a1)+,d4	;get pixel colour

	move d7,d0
	swap d0
	clr d0
	move.l d0,GPU_RAM+$fe8
	move d6,d0
	swap d0
	clr d0
	move.l d0,GPU_RAM+$fe4
	move d4,d0
;	asr #8,d0
	and #$ff,d0
	swap d0
	clr d0
	move.l d0,GPU_RAM+$fdc
	move d4,d0		;get colour
;	asr #8,d0		;extract colour vector
	and #$ff,d0
	neg d0
	move tzp,d4
	asr #2,d4
	add #$40,d4
	add d4,d0
	ext.l d0		;make signed long
	swap d0
	move.l d0,GPU_RAM+$fe0
 	move.l #-1,gpu_sem	;flag GPU running
	move.l #$403000,d0	;start address of GPU program
	swap d0			;for GPU endian-ness
	move.l d0,GPU_PC	;set GPU's PC
	move.l #$11,d0		;GPU_GO is 1
	swap d0
	move.l d0,GPU_CTRL	;fire up GPU	
s_running: tst.l gpu_sem
	bmi s_running	;wait for GPU stop
;	move d7,-(a7)
;	bsr WaitBlit			
;	move (a7)+,d7
	sub #16,d7
	sub #1,d2
	bne gpix2
	lea 320(a0),a0
	sub #16,d6
	sub #1,d3
	bne gpix	
	move #1,screen_ready
	rts 

rotatestuff: move.b gpu_data,d0
	and #$ff,d0			;these bits only for
	lea sines,a1			;rotate and tilt
	move.b 0(a1,d0.w),d0		;
	ext d0				;
	add #$81,d0			;
	asl #1,d0			;
	and.l #$fff,d0			;
	swap d0				
	move.l d0,GPU_RAM+$ff4
	
	move #160,d3		;centre point of rotation
	move #100,d4
	move rot_scale,d5
	add #$20,d5
	move pointer,d7
	asl #1,d7
	and #$ff,d7
	move.b 0(a1,d7.w),d0
	ext d0
	ext.l d0
	muls d5,d0
	asr.l #7,d0
	add d3,d0
	add.b #$40,d7
	move.b 0(a1,d7.w),d1
	ext d1
	ext.l d1
	muls d5,d1
	asr.l #7,d1
	add d4,d1
	move.l #GPU_RAM+$ff8,a0
	bsr WriteGPU

	sub.b #$80,d7

	move.b 0(a1,d7.w),d0
	ext d0
	ext.l d0
	muls d5,d0
	asr.l #7,d0
	add d3,d0
	add.b #$40,d7
	move.b 0(a1,d7.w),d1
	ext d1
	ext.l d1
	muls d5,d1
	asr.l #7,d1
	add d4,d1		;second point
	move.l #GPU_RAM+$ff0,a0
	bsr WriteGPU
	add.b #$40,d7
	move.b 0(a1,d7.w),d0
	ext d0
	ext.l d0
	muls d5,d0
	asr.l #7,d0
	add d3,d0
	add.b #$40,d7
	move.b 0(a1,d7.w),d1
	ext d1
	ext.l d1
	muls d5,d1
	asr.l #7,d1
	add d4,d1		;third point	
	move.l #GPU_RAM+$fe8,a0
WriteGPU: move d0,d2
	swap d2
	move d1,d2
	move.l d2,(a0)
	rts
bigfp: move.l #6,d0
	bra fpr
fp_rotatestuff: move.l #1,d0
fpr:	swap d0
	move.l d0,GPU_RAM+$ffc
 	move.b gpu_data,d0
;	asl #1,d0
	and #$ff,d0			;these bits only for
	lea sines,a1			;rotate and tilt
	move.b 0(a1,d0.w),d0		;
	ext d0				;
	add #$81,d0			;
	add #20,d0
;	asl #1,d0
;	move #80,d0
	and.l #$ffff,d0			;	
	swap d0				
	move.l d0,GPU_RAM+$ff4
	bsr run_rotate_vars
	lea sines,a1
	move cpx,d3			;centre point x and y
	move cpy,d4
	swap d3
	clr d3
	swap d4
	clr d4				;to 16:16
	move rot_scale,d5
	asl #4,d5
	move pointer2,d7
	and #$ff,d7
	move.b 0(a1,d7.w),d0
	ext d0
	ext.l d0
	muls d5,d0
	asl.l #5,d0
	add.l d3,d0
	swap d0
	move.l d0,GPU_RAM+$ff8
	add.b #$40,d7
	move.b 0(a1,d7.w),d1
	ext d1
	ext.l d1
	muls d5,d1
	asl.l #5,d1
	add.l d4,d1
	swap d1
	move.l d1,GPU_RAM+$ff0

	sub.b #$80,d7
	move.b 0(a1,d7.w),d0
	ext d0
	ext.l d0
	muls d5,d0
	asl.l #5,d0
	add.l d3,d0
	swap d0
	move.l d0,GPU_RAM+$fe8
	add.b #$40,d7
	move.b 0(a1,d7.w),d1
	ext d1
	ext.l d1
	muls d5,d1
	asl.l #5,d1
	add.l d4,d1		;second point
	swap d1
	move.l d1,GPU_RAM+$fe4

	add.b #$40,d7
	move.b 0(a1,d7.w),d0
	ext d0
	ext.l d0
	muls d5,d0
	asl.l #5,d0
	add.l d3,d0
	swap d0
	move.l d0,GPU_RAM+$fe0
	add.b #$40,d7
	move.b 0(a1,d7.w),d1
	ext d1
	ext.l d1
	muls d5,d1
	asl.l #5,d1
	add.l d4,d1		;third point	
	swap d1
	move.l d1,GPU_RAM+$fdc
	rts

f_rotatestuff:	move.l #2,d0
	swap d0
	move.l d0,GPU_RAM+$ffc
	move #160,cpx
	move #100,cpy
f_ro: 	bsr run_rotate_vars


;	bsr run_tf_vars
	lea sines,a1
	move cpx,d3			;centre point x and y
	move cpy,d4
	swap d3
	clr d3
	swap d4
	clr d4				;to 16:16
	move rot_scale,d5
	asl #4,d5
	move pointer2,d7
	and #$ff,d7
	move.b 0(a1,d7.w),d0
	ext d0
	ext.l d0
	muls d5,d0
	asl.l #5,d0
	add.l d3,d0
	swap d0
	move.l d0,GPU_RAM+$ff8
	add.b #$40,d7
	move.b 0(a1,d7.w),d1
	ext d1
	ext.l d1
	muls d5,d1
	asl.l #5,d1
	add.l d4,d1
	swap d1
	move.l d1,GPU_RAM+$ff0

	sub.b #$80,d7
	move.b 0(a1,d7.w),d0
	ext d0
	ext.l d0
	muls d5,d0
	asl.l #5,d0
	add.l d3,d0
	swap d0
	move.l d0,GPU_RAM+$fe8
	add.b #$40,d7
	move.b 0(a1,d7.w),d1
	ext d1
	ext.l d1
	muls d5,d1
	asl.l #5,d1
	add.l d4,d1		;second point
	swap d1
	move.l d1,GPU_RAM+$fe4

	add.b #$40,d7
	move.b 0(a1,d7.w),d0
	ext d0
	ext.l d0
	muls d5,d0
	asl.l #5,d0
	add.l d3,d0
	swap d0
	move.l d0,GPU_RAM+$fe0
	add.b #$40,d7
	move.b 0(a1,d7.w),d1
	ext d1
	ext.l d1
	muls d5,d1
	asl.l #5,d1
	add.l d4,d1		;third point	
	swap d1
	move.l d1,GPU_RAM+$fdc
	rts


gradstuff:
;
; Transfers line gradients for the horizontal line scale
; GPU thang

	bsr run_grad_vars
	move grad,d0
	sub #$3ff,d0
	bpl grad1
	neg d0
	bpl grad1
	clr d0
grad1:	sub #$1ff,d0
	ext.l d0
	asl.l #8,d0
	asl.l #2,d0 
	swap d0
	move.l d0,GPU_RAM+$ff0	;initial gradient of map edge
	move grad2,d0
	sub #$3ff,d0
	bpl grad3
	neg d0
	bpl grad3
	clr d0
grad3:	sub #$1ff,d0
	ext.l d0
	asl.l #4,d0
	swap d0
	move.l d0,GPU_RAM+$ff8	;change of gradient
gpud:	move.b gpu_data,d0
	and.l #$ff,d0
	swap d0
	move.l d0,GPU_RAM+$ff4
	rts

run_rotate_vars:
	move p2inc,d0 
	add d0,pointer2
 	move.l rot_scale,d0
	move.l rot_scale_add,d1
	add.l rot_scale_grav,d1
	sub.l d1,d0
	bpl rgpuv1
	neg.l d1
	sub.l d1,d0	
rgpuv1:	move.l d0,rot_scale
	move.l d1,rot_scale_add
	add.b #1,gpu_data
	rts


sinestuff: move.l sws1,d0
	add.l swp1,d0
	move.l d0,swp1
	swap d0
	move.l d0,GPU_RAM+$ff8
	move.l sws2,d0
	add.l swp2,d0
	move.l d0,swp2
	swap d0
	move.l d0,GPU_RAM+$ff0
rgv: move gpui,d1
	move gpu_data,d0
	add d1,d0
	bpl rgv0
	add #400,d0
	bra rgv01
rgv0:	cmp #400,d0
	blt rgv01
	sub #399,d0
rgv01:	move d0,gpu_data
	and.l #$ffff,d0
	sub.l #199,d0
	bpl gnottu
	neg.l d0
gnottu:	swap d0
	move.l d0,GPU_RAM+$ff4
	rts 


run_grad_vars:
	move gpui,d1
	move.b gpu_data,d0
	and #$ff,d0

	add d1,d0
	bpl rgv1
	add #200,d0
	bra glok
rgv1:	cmp #200,d0
	blt glok
	sub #200,d0
glok:	move.b d0,gpu_data 
rgv2:	move g1i,d0
 	add d0,grad		;change vars in gpu-space
	and #$7ff,grad
	move g2i,d0
	add d0,grad2		;change vars in gpu-space
	and #$7ff,grad2
	
	rts



InitBeasties: lea beasties,a0
 move nbeasties,d7
ibeasts: move #-1,12(a0)	;inactive
 lea 64(a0),a0			;room for other shit
 dbra d7,ibeasts
 rts

RunBeasties: move.l blist,a0		;will use MakeScaledObject to build a list
 tst pong_on
 beq nomidline
 move.l midobj,a1			;draw Pong centre line
 move #66,d1
 move #32+152,d0
 move #0,d2
 move.l #$90200001,d3
 move #43,d4
 move #0,d5
 bsr MakeScaledObject

nomidline: lea beasties,a2
 move nbeasties,d7

RBeasts: move d7,-(a7)
 move 12(a2),d0	; get mode
 bmi nxbeast
 move 38(a2),d6
 beq keepold
 add 44(a2),d6
 move d6,44(a2)
 and #$1ff,d6
 sub #$ff,d6
 bpl gnome2
 neg d6
gnome2: add #$7f,d6
 move d6,8(a2)

keepold: move 40(a2),d6
 beq keepoldy
 add 42(a2),d6
 move d6,42(a2)
 and #$1ff,d6
 sub #$ff,d6
 bpl gnome3
 neg d6
gnome3: lsr #2,d6
 add #$8,d6
 move d6,10(a2)
keepoldy: lea ModeVex,a3
 asl #2,d0
 move.l 0(a3,d0.w),a3
 jsr (a3)		;call action for that Mode
 move (a2),d0
 move 4(a2),d1
 bclr #0,d1
 move 8(a2),d6
 move 10(a2),d3
 lsl #8,d3
 swap d3
 move 14(a2),d7		;type
 lea ObTypes,a3
 asl #3,d7
 move 0(a3,d7.w),d3	;get width in phrases
 move 2(a3,d7.w),d4	;vertical height
 move 4(a3,d7.w),d5	;depth
 move.l 16(a2),a1	;data pointer
 clr.l d2
 bsr cro_x
nxbeast: move (a7)+,d7
 lea 64(a2),a2		;do 'em all 
 dbra d7,RBeasts
 tst pong_on
 beq StopList
 bsr RunPong
 bra StopList		;put a stopobject on the end  

ModeVex: dc.l nothing,d_vbounce,x_linear,vbounce,vfall,x_wrap,xy_wrap
	dc.l robot,orbit
RunPong: move pbx,d0
rp1:	add pvx,d0
	cmp #72,d0
	blt bncex
	cmp #297,d0
	blt rp2
bncex:	neg pvx
	bra rp1
rp2:	move d0,pbx
	move pby,d0
rp3:	add pvy,d0
	cmp #66,d0
	blt bncey
	cmp #438,d0
	blt rp4
bncey: 	neg pvy
	bra rp3
rp4:	move d0,pby
	sub #20,d0
	cmp #66,d0
	bgt rp5
	move #66,d0
rp5:	cmp #320+66,d0
	blt rp6
	move #320+66,d0
rp6:	tst pvx
	bpl rp7
	move bat1,d1
	move d1,d3
	move #2,d2
	sub d0,d1
	bpl rp61
	neg d1
	neg d2
rp61:	cmp #2,d1
	ble rp62
	move d3,d0
	sub d2,d0	
rp62:	move d0,bat1
	bra rp8
rp7:	move bat2,d1
	move d1,d3
	move #2,d2
	sub d0,d1
	bpl rp71
	neg d1
	neg d2
rp71:	cmp #2,d1
	ble rp72
	move d3,d0
	sub d2,d0	
rp72: 	move d0,bat2
rp8:


 lea $14000,a1			;draw Pong border left
 move #66,d1
 move #32,d0
 move #5,d2
 move.l #$80200001,d3
 move #48,d4
 move #0,d5
 bsr MakeScaledObject




 lea $14000,a1			;draw Pong border right
 move #66,d1
 move #320+16,d0
 move #1,d2			;colour 1
 move.l #$80200001,d3
 move #48,d4
 move #0,d5
 bsr MakeScaledObject
 move -14(a0),d0
 bset #13,d0
 move d0,-14(a0)		;make it reflected

 lea $14020,a1			;draw Pong bat left
 move bat1,d1 
 move #64,d0
 move #2,d2
 move.l #$80200001,d3
 move #8,d4
 move #0,d5
 bsr MakeScaledObject

 lea $14020,a1			;draw Pong bat right
 move bat2,d1
 move #304,d0
 move #3,d2
 move.l #$80200001,d3
 move #8,d4
 move #0,d5
 bsr MakeScaledObject

 lea $14020,a1			;draw Pong ball
 move pby,d1
 move pbx,d0
 move #4,d2
 move.l #$80200001,d3
 move #2,d4
 move #0,d5
 bra MakeScaledObject


nothing: rts


x_wrap: move 22(a2),d3
	sub 20(A2),d3
	move.l (a2),d0
	add.l 24(a2),d0
	swap d0
	cmp 20(a2),d0
	bgt x_wr1
	add d3,d0
	bra xm_ok
x_wr1:	cmp 22(a2),d0
	blt xm_ok
	sub d3,d0
	bra xm_ok

xy_wrap: move 34(a2),d3
	sub 32(A2),d3
	move.l 4(a2),d0
	add.l 28(a2),d0
	swap d0
	cmp 32(a2),d0
	bgt y_wr1
	add d3,d0
	bra yw_ok
y_wr1:	cmp 22(a2),d0
	blt yw_ok
	sub d3,d0
yw_ok: swap d0
	move.l d0,4(a2)
	bra x_wrap


x_linear: move.l (a2),d0
xl:	add.l 24(a2),d0
	swap d0
	cmp 20(a2),d0
	bmi x_refl
	cmp 22(a2),d0
	bmi xm_ok
x_refl:	swap d0
	neg.l 24(a2)
	bra xl
xm_ok:  swap d0
	move.l d0,(a2)
	rts

d_vbounce: move.l 32(a2),d0
	add.l d0,28(a2)
 	move.l 4(a2),d0
d_vb:	add.l 28(a2),d0
	swap d0
	cmp 36(a2),d0
	blt ym_ok
	move.l 28(a2),d1
	bmi ym_ok
	sub #1,46(a2)
	bpl stillbounce
	move 36(a2),4(a2)
	move #2,12(a2)	;mode to Xlinear only
	bra x_linear
stillbounce: neg.l d1
	move.l d1,d2
	asr.l #1,d2
	asr.l #2,d1
	add.l d2,d1
	move.l d1,28(a2)
	swap d0
	bra d_vb
ym_ok:  swap d0
	move.l d0,4(a2)
	bra x_linear

vbounce: move.l 32(a2),d0
	add.l d0,28(a2)
 	move.l 4(a2),d0
vb:	add.l 28(a2),d0
	swap d0
	cmp 36(a2),d0
	blt ym_ok
vb0:	neg.l 28(a2)
	swap d0
	bra vb

vfall:  move.l 32(a2),d0
	add.l d0,28(a2)
 	move.l 4(a2),d0
	add.l 28(a2),d0
	swap d0
	cmp 36(a2),d0
	blt ym_ok
	move #-1,12(a2)
	rts

orbit: lea beasties+128,a3
	lea sines,a4
	add #1,48(a2)
	move 48(a2),d0
	and #$ff,d0
	move.b 0(a4,d0.w),d1
	ext d1
	add (a3),d1
	move.l 50(a2),d2
	add.l d2,54(a2)
	move 54(a2),d2
	and #$ff,d2
 	move.b 0(a4,d2.w),d2
	ext d2
;	asr #2,d2
;	add d2,d1
	swap d1
	move.l d1,(a2)
	add.b #$40,d0
	move.b 0(a4,d0.w),d1
	ext d1
	asl #1,d1
	add 4(a3),d1
	add d2,d1
	swap d1
	move.l d1,4(a2)
	move.l 16(a3),16(a2)
	move #$40,d0
	move 8(a3),d1
	cmp #$80,d1
	blt zoop
	move #$c0,d0
zoop: 	move d0,8(a2)
	rts

robot:	add #1,pointer
	and #3,pointer
	add #2,pointer2
	lea sines+256,a3
	move pointer2,d0
	and #$ff,d0
	move.b 0(a3,d0.w),d0
	lsr #2,d0
	add #$20,d0
	move d0,beasties+10
	move d0,beasties+74
	move 48(a2),d0
	move.l #12800,d1
	mulu d0,d1
	add.l #RobotBase,d1
	move.l d1,16(A2)
	move 52(a2),d0
	asl #2,d0
	lea rmm,a3
	move.l 0(a3,d0.w),a3
	jsr (a3)	;call motion/ani vector
	lea sines,a3
	move 54(a2),d0
	add #24,d0
	swap d0
	clr d0
	move.l d0,(a2)	;set true X
	move 50(a2),d1
	and #$ff,d1
	move.b 0(a3,d1.w),d1
	ext d1
	asr #2,d1
 	move 56(a2),d0
	asl #1,d0
	add #TOP,d0
	add d1,d0
	swap d0
	move.l d0,4(a2)
	move.l 60(a2),d0
	move.l d0,beasties+24
	move.l d0,beasties+88
	move #$7f,8(a2)
	tst 60(a2)
	bpl rrts
	move #$80,8(a2)
	rts

rmm: dc.l rise,wobble,accleft,turn,accright,turn,gleft

rise:	tst pointer
	bne rise1
	add #1,48(a2)
	cmp #16,48(a2)
	ble rise1
	move #14,48(a2)
rise1: 	sub #1,56(a2)
	cmp #120,56(a2)
	bgt rrts
	move #1,52(a2)
	move #300,58(a2)
	rts

wobble:	tst pointer
	bne wobb1
	add #1,48(a2)
	cmp #16,48(a2)
	ble wobb1
	move #14,48(a2)
wobb1:
 	add #1,50(a2)
	sub #1,58(a2)
	bpl rrts
	add #1,52(a2)
	move #13,48(a2)
	rts

accleft: tst pointer
	bne accl1
	sub #1,48(a2)
	cmp #6,48(a2)
	bge accl1
	move #8,48(a2)

accl1: 	sub.l #$800,60(a2)
 	add #1,50(a2)
	cmp #-16,60(a2)
	bne rrts
	move #3,52(a2)
	move #8,58(a2)		;gun shots
	move #0,48(a2)		;raise arms
	rts

turn: tst pointer
	bne turn11
	tst 58(a2)
	bmi doturn
	bne dofire
	sub #1,48(a2)
	bpl turn11
	move #6,48(a2)
	move #-1,58(a2)
	bra turn11
dofire:	add #1,48(a2)
	cmp #5,48(a2)
	ble turn11
	move #3,48(a2)
	sub #1,58(a2)
	bra turn11	
doturn:	add #1,48(a2)
	cmp #16,48(a2)
	ble turn11
turn1: move #14,48(a2)

turn11:	move.l #$800,d1
	add #1,50(a2)
	move.l 60(a2),d0
	bmi turn2 
	neg.l d1
turn2:	add.l d1,60(a2)
	bne rrts
	add #1,52(a2)
 
accright: tst pointer
	bne accr1
 	sub #1,48(a2)
	cmp #6,48(a2)
	bge accr1
	move #8,48(a2)
accr1: add.l #$800,60(a2)
 	add #1,50(a2)
	cmp #16,60(a2)
	bne rrts
	move #5,52(a2)
	move #8,58(a2)		;gun shots
	move #0,48(a2)		;raise arms
	rts	

gleft: move #2,52(a2)
	rts

sfrob: move 60(a2),d0
	bpl sfr1
	neg d0
sfr1: lsr #1,d0
	move d0,48(a2)
stoprob: add #1,50(a2)
	rts

hover: add #1,pointer
	move pointer,d0
	lsr #6,d0
	and #$0f,d0
	move d0,48(a2)
	bra stoprob

*------------ routines

InitLists:
;
; Align object list buffers and initialise them with some
; data, set one of them to be displayed

	move.l #list1,d0
	and.l #$ffffffe0,d0	;make sure it's quadphrase aligned
	sub.l #8,d0		;so that cond objs leave list quad aligned
	move.l d0,dlist
	move.l d0,a0
	bsr MakeTestList 

	move.l #list2,d0	;same for the other list
	and.l #$ffffffe0,d0	;make sure it's quadphrase aligned
	sub.l #8,d0		;so that cond objs leave list quad aligned
	move.l d0,blist
	move.l d0,a0
	bra MakeTestList 

MakeTestList:
;
; enter with a0.l set to the start of the list you wanna build

	move #50,d0
	move #100,d1		;X and Y
	clr d2
	lea testobject,a1
	and.l #$ffffffe0,d2	;address of the object
				;NB SCALED BM OBJECTS MUST START
				;ON A QUAD PHRASE BOUNDARY!!!!!
	move.l #$20080001,d3		;one phrase wide, scale=1
	move #16,d4		;16 scanlines high
	move #0,d5			;one bit per pixel
	bsr MakeScaledObject		;make a Thang
 	add #80,d0
	bsr MakeScaledObject
	add #80,d0
	bsr MakeScaledObject
StopList:	move.l #0,(a0)+
	move.l #4,(a0)+		;make a stopobject
	rts

cro_x:
;
; This is a Make Scaled Object variant. d0 represents the
; x-centre of the object.  Yscale is passed in the top of d3,
; as usual, but d6 holds a signed byte value which is used
; to scale the object horizontally, flipping if it is
; negative.  Works for 16-bit objects only!
;
; Y is centered, and clipping of the top is performed.  This is
; nontrivial for scaled objects and would be more efficiently done
; on the GPU if you have a lot of scaled Objects needing clipping.

;	cmp #TOP+464,d1
;	bpl rrts		;ignore if off bottom

	move d2,-(a7)		;free a reg to work wiv

	move d3,d2		;get object width in phrases
	asl #2,d2		;width of object in words (pixels
				;for 16-bits)
	asr #1,d2		;half the width
	clr d7
	ext d6
	bpl cro_1		;check sign of scaling
	neg d6
	bset #13,d7	;d7 will hold the reflect bit
	neg d2		;offset at rhs of image
cro_1:  move d7,-(a7)
	move scaleshift,d7
	lsr d7,d6	;make scale range 0-1.F off
	ext.l d2	;pixel count to longword
	muls d6,d2	;multiply by scale value
	asr.l #5,d2	;normalise
	sub d2,d0	;calc X start
	and #$fff,d0	;limit X to a 12-bit value
	swap d3
	move d3,d2	;get Y scale to calc Y centering
	or d6,d3	;put X scale in
	swap d3		;restore to right order
	lsr #8,d2	;y scale to bottom of byte
	move d0,-(a7)	;save xpos
	move d4,d0	;get height of object in scanlines
	asl #1,d0	;make it halflines
	ext.l d0	;to long
	mulu d2,d0	;make total height of object
	asr.l #6,d0	;normalise and halve
	sub d0,d1	;adjust y-position to centre
	move d1,d7
	add d0,d7
	add d0,d7	;calculate bottom position of object
	cmp #TOP,d7	;is bottom of object above top of display?
	bpl do_it	;no, some of the object is on screen
	move (a7)+,d0
	move (a7)+,d7
	move (a7)+,d2	;unstack the stuff
	rts		;history

do_it:	cmp #TOP,d1	;check for top of screen
	bpl y_was_easy	;if it is positive, we were lucky.
	sub #TOP,d1	;calculate overshoot
	neg d1		;make overshoot positive
	sub #2,d1
	bmi nhr		;effectively if <2 no action
	ext.l d1	;and long
	move.l d1,d7	;save it
	asl #4,d1	;adjust (/2 implicit to convert back from hlines)
	divu d2,d1	;divide by scale
	sub d1,d4	;reduce height of Object
	ext.l d1
	mulu d3,d1	;get number of phrases to skip
	asl.l #3,d1	;convert to a byte value
	add.l d1,a1	;update the data pointer by that amount
nhr:	move d2,d1	;get scale
	lsr #5,d1	;get int of scale
	bne scalegr	;greater than 1, got to go calculate remainder
	clr d1		;set Y=0 and go do it
	bra y_was_easy
scalegr: lsr #1,d7
	divu d1,d7
	swap d7		;overhang MOD(INT(scale))
	lsl #5,d7	;make correct format
	move d7,d1
	move (a7)+,d0
	move (a7)+,d7
	move (a7)+,d2
	move d1,-(a7)	;save updated Remainder
	move #TOP,d1		;set start line to 0			
	bsr mso		;make the Object
	move (a7)+,d7	;get remainder back
	and #$ff,d7
	move -4(a0),d0
	and #$ff,d0
	sub d7,d0
	move d0,-4(a0)
	rts

	
y_was_easy: and #$3ff,d1	;make Y value a 10-bit field
	cmp #$20,d2
	bge nofudge
	sub #4,d4
nofudge:	move (a7)+,d0	
	move (a7)+,d7	;get the reflect bit
	
	move (a7)+,d2	;get back mashed d2
mso:	move d7,-(a7)
	bsr MakeScaledObject	;make the object
	move (a7)+,d7
	move -14(a0),d0
	or d7,d0	;mask in the reflect bit
	move d0,-14(a0)	;replace
	rts

	 

MakeScaledObject:
;
; Make an OL entry for an object. a0 --> current pos in OL being built
; (assumes a0 is already phrase aligned)
;	d0-d1 = x,y
;	d2 = index into CLUT
;	d3 = X size, in phrases
;	d4 = Y size, in scan lines
;	d5 = Object depth
;	a1.l = address of data
;
; uses all d-regs, a0 must have OL position, a6 used internally
;
; Adding new stuff: d3 high word now=Yscale:Xscale


* First, make a conditional object because of the bug in OLP

	move.l a0,d6
	add.l #32,d6		;length of scaled BM object + this object
	and.l #$fffffff8,d6	;lose 3 lsb's (see below)
	move.l d6,a6		;save it for later on...
	lsl.l #5,d6		;put the bits in the right place
				;(It is 5 and not 8, because it's a
				;phrase address, so the three low bits are
				;not used)
	clr (a0)+		;first word is unused
	move.l d6,(a0)+		;write branch address

* Now, calculate where the branch is gonna be...

	move.l d3,d7		;get Y stuff
	swap d7			;get Yscale and Xscale

scalup:	lsr #8,d7		;get Y scale
	mulu d4,d7		;multiply y size
	lsr #5,d7		;normalise
	asl #1,d7		;x2 coz it's in half lines

dscale:	move d1,d6		;Y start
	add d7,d6
	lsl #3,d6		;shift to correct bit position
	or #%1000000000000011,d6	;mask in CC and type
	move d6,(a0)+		;and this completes the cond obj.


* Now the funky bit. Build a scaled bitmapped object.
* It is scaled, because of yet another bug in OLP.
* We are now on a quadphrase boundary too.

	move.l a1,d6		;get copy of data pointer
	and.l #$fffffff8,d6	;lose three LSB's
	move #9,d7		;shift counter
	lsl.l d7,d6		;move to correct bit position
	move.l d6,(a0)+		;put it in the list

* The link address is the same as for the preceding conditional
* object, and remember i saved it in a1, so...

	move.l a6,d6		;get back link-pointer
	lsl.l #5,d6		;make it aligned OK (bott. 3 bits are 0)
	swap d6			;get top word of the address..
	or d6,-2(a0)		;and or it into place on the previous word.

* That's the first longword done, and the remaining byte of the
* link address is in d6 high already.

	move.l #0,d7		;make d7 empty
	move d4,d7		;get a copy of the height...
	ror.l #2,d7		;put 2 lowest bits in hi word...
	swap d6			;get back rest of link
	or d7,d6		;OR in top 8-bits of height..
	move d6,(a0)+		;top word now completed..
	swap d7			;get 2 lowest bits of height at top of d7..
	move d1,d6		;copy of Y pos..
	lsl #3,d6		;align...
	or d7,d6		;mask in those 2 bits of height..
	bset #0,d6		;set the type=1
	move d6,(a0)+		;..which completes the first phrase.

* Now on to the next phrase.

	clr (a0)+		;assume Firstpix=0, RELEASE not asserted
	move d2,d7		;get INDEX
	lsl #7,d7		;align it
	move.l #0,d6		;empty d6
	move d3,d6		;get X size in phrases
	ror.l #4,d6		;shift low 4 bits into hi word
	bset #15,d6		;set transparency
	or d7,d6		;mask in Index
	move d6,(a0)+		;ignores Reflect, RMW

* First long of phrase 2 is done...

	move d3,d7		;Assume dwidth=iwidth for simplicity
	lsl #2,d7		;align
	swap d6			;get top of d6, which has rest of iwidth
	or d7,d6		;mask in dwidth	
	move d6,(a0)+		;put it in, assume pitch is 1
	move d5,d6		;get copy of depth
	ror #4,d6		;put it in top byte
	or d0,d6		;Hallelujah! X doesn't need shifting!
	bset #15,d6		;(PITCH=1)
	move d6,(a0)+		;Here endeth the Second Phrase.

* Now the third and final phrase.

	move.l #0,(a0)+		;Not used.....
	move.l d3,d6
	clr.l d7
 	swap d6			;get x- and y-scale
	move d6,d7		;copy scales
	lsr #8,d7
	swap d7
 	move d6,d7		;recombine remainder with d7
	move.l d7,(a0)+	


* Outta here.

	rts

cls160:	move.l #PITCH1|PIXEL16|WIDTH160|XADDPHR,d7
	swap d7			;for right Endian-ness
	move.l d7,BLIT_A1FLAGS
	move.l a0,d7
	swap d7
	move.l d7,BLIT_A1BASE	;base of dest screen
	clr.l d7
	move.l d7,BLIT_A1PIXEL
	move.l d7,BLIT_A1PIXELF
	move #-160,d7
	swap d7
	move #1,d7		;X and Y Step
	move.l d7,BLIT_A1STEP
	move.l #0,BLIT_A1STEPF	;no fraction of step
	move #160,d7
	swap d7
	move #100,d7		;Inner and outer loop count
	move.l d7,BLIT_COUNT
	move d0,d7		;get colour
	swap d7
	move d0,d7		;duplicate
	move.l d7,BLIT_PATD
	move.l d7,BLIT_PATD+4	;fill up phrase wide pattern register
	move.l #PATDSEL|UPDA1,d7
	swap d7
	move.l d7,BLIT_CMD	;do the thang
	bra WaitBlit


cls8:
;
; clear an 8bpp screen (a0) to colour (d0)

	move.l #PITCH1|PIXEL8|WIDTH320|XADDPHR,d7
	swap d7			;for right Endian-ness
	move.l d7,BLIT_A1FLAGS
	move.l a0,d7
	swap d7
	move.l d7,BLIT_A1BASE	;base of dest screen
	clr.l d7
	move.l d7,BLIT_A1PIXEL
	move.l d7,BLIT_A1PIXELF
	move #-320,d7
	swap d7
	move #1,d7		;X and Y Step
	move.l d7,BLIT_A1STEP
	move.l #0,BLIT_A1STEPF	;no fraction of step
	move #$140,d7
	swap d7
	move #200,d7		;Inner and outer loop count
	move.l d7,BLIT_COUNT
	move d0,d7		;get colour
	swap d7
	move d0,d7		;duplicate
	move.l d7,BLIT_PATD
	move.l d7,BLIT_PATD+4	;fill up phrase wide pattern register
	move.l #PATDSEL|UPDA1,d7
	swap d7
	move.l d7,BLIT_CMD	;do the thang
	bra WaitBlit

BlitBlock:
;
; use the Blitter to draw a block, origin d0/d1, size d2/d3, colour d4,
; on the 320-pixel wide bitmap addressed at a0.

	move.l #PITCH1|PIXEL16|WIDTH320|XADDINC,d7
	swap d7			;for right Endian-ness
	move.l d7,BLIT_A1FLAGS
	move.l a0,d7
	swap d7
	move.l d7,BLIT_A1BASE	;base of dest screen
	move d0,d7
	swap d7
	move d1,d7		;X and Y destination start
	move.l d7,BLIT_A1PIXEL
	move.l #0,BLIT_A1PIXELF
	move #1,d7
	swap d7
	clr d7			;X and Y Increment values
	move.l d7,BLIT_A1INC
	move.l #0,BLIT_A1INCF	;No fractional parts of increment
	move d2,d7
	neg d7
	swap d7
	move #1,d7		;X and Y Step
	move.l d7,BLIT_A1STEP
	move.l #0,BLIT_A1STEPF	;no fraction of step
	move d2,d7
	swap d7
	move d3,d7		;Inner and outer loop count
	move.l d7,BLIT_COUNT
	move d4,d7		;get colour
	swap d7
	move d4,d7		;duplicate
	move.l d7,BLIT_PATD
	move.l d7,BLIT_PATD+4	;fill up phrase wide pattern register
	move.l #PATDSEL|UPDA1,d7
	swap d7
	move.l d7,BLIT_CMD	;do the thang

WaitBlit: move.l BLIT_CMD,d7	;get Blitter status regs
	swap d7
	btst #11,d7
	beq WaitBlit		;wait until outer loop is idle
rrts:	rts



BlitLine:
;
; draw a line with the blitter from d0/d1 to d2/d3, colour d4
; on a 320-pixel-wide 16-bit screen at a0.

* first set up the usual gubbins

	move.l #PITCH1|PIXEL16|WIDTH320|XADDINC,d7
	swap d7			;for right Endian-ness
	move.l d7,BLIT_A1FLAGS
	move.l a0,d7
	swap d7
	move.l d7,BLIT_A1BASE	;base of dest screen
	move d0,d7
	swap d7
	move d1,d7
	move.l d7,BLIT_A1PIXEL
	move.l #0,BLIT_A1PIXELF	;set startpoint of line

	move d2,d5
	sub d0,d5	;delta x
	beq do_vline	;do trivial case if delta x is 0

	swap d5
	move d3,d5
	sub d1,d5	;delta y
	beq do_hline	;do hline if delta y is 0

	move d5,d7
	bpl blin1
	neg d7		;d7 holds abs value of delta y
blin1:	swap d5
	move d5,d6
	bpl blin2
	neg d6		;d6 holds abs value of delta x
blin2:  cmp d7,d6	;see which is larger
	beq do_diagline
	bgt x_larger	;go do x greater version

y_larger: swap d7	;y greater, so is the inner loop count
	move #1,d7	;outer loop count is one
	move.l d7,BLIT_COUNT
	swap d7		;restore delta Y!

	move d5,d6	;get signed dx...
	swap d6
	clr d6		;effectively <<16
	asr.l #1,d6
	divs d7,d6	;divide by absolute integer Y-difference 	
	ext.l d6	;get sign in top of d6
	swap d6		;contains 0 or 1, sign of integer part

	move d6,d7	;signed integer X increment
	swap d7
	move #1,d7	;Y-integer is one...	
	swap d5		;get back signed dy
	tst d5
	bpl y_larg1
	neg d7		;make it the right sign
y_larg1: move.l d7,BLIT_A1INC	;set integer parts of the increment
	and.l #$ffff0000,d6	
	asl.l #1,d6
	move.l d6,BLIT_A1INCF	;set frac parts of increment	
	bra setrest

x_larger: swap d6	;x greater, make it the inner loop count
	move #1,d6
	move.l d6,BLIT_COUNT 
	swap d6		;restore delta X!

	swap d5
	move d5,d7	;get signed dy...
	swap d7
	clr d7		;effectively <<16
	asr.l #1,d7
	divs d6,d7	;divide by absolute integer X-difference 	
	ext.l d7
	swap d7		;contains 0 or 1, sign of integer part

	move #1,d6	;X-integer is one...	
	swap d5		;get back signed dx
	tst d5
	bpl x_larg1
	neg d6		;make it the right sign
x_larg1: swap d6
	move d7,d6	;sign from d7
	move.l d6,BLIT_A1INC	;set integer parts of the increment
	swap d7		;get frac part
	asl #1,d7
	and.l #$ffff,d7	
	move.l d7,BLIT_A1INCF	

setrest: move d4,d5		;set colour
	swap d5
	move d4,d5		;dupe
	move.l d5,BLIT_PATD
	move.l d5,BLIT_PATD+4
	move.l #PATDSEL,d7
	swap d7
	move.l d7,BLIT_CMD 	;go
	bra WaitBlit		;don't return until blitter is ready

do_vline: movem d0-d3,-(a7)
 	cmp d3,d1
	beq zlength		;zero length
	blt noswap_v
	exg d3,d1		;swap regs
noswap_v: move d0,d7
	swap d7
	move d1,d7
	move.l d7,BLIT_A1PIXEL
	move.l #1,BLIT_A1INC		;only increment Y
	move.l #0,BLIT_A1INCF
	move d3,d7
	sub d1,d7
	bra linego

do_hline: movem d0-d3,-(a7)
	cmp d2,d0
	beq zlength		;zero length
	blt noswap_h
	exg d2,d0		;swap regs
noswap_h: move d0,d7
	swap d7
	move d1,d7
	move.l d7,BLIT_A1PIXEL
	move.l #$10000,BLIT_A1INC		;only increment X
	move.l #0,BLIT_A1INCF
	move d2,d7
	sub d0,d7
linego:	swap d7
	move #1,d7
	move.l d7,BLIT_COUNT
	bsr setrest
zlength: movem (a7)+,d0-d3
 	rts

do_diagline: move #1,d6		;handle trivial case where dx=dy
	move d2,d5
	sub d0,d5
	bpl d_dl1
	neg d6
d_dl1:	swap d6
	move #1,d6
	move d3,d5
	sub d1,d5
	bpl d_dl2
	neg d6
	neg d5
d_dl2: move.l d6,BLIT_A1INC
	move.l #0,BLIT_A1INCF
	swap d5
	move #1,d5
	move.l d5,BLIT_COUNT
	move d0,d5
	swap d5
	move d1,d5
	move.l d5,BLIT_A1PIXEL
	bra setrest
			
CopyBlock:
;
; Copy from screen at a0 to screen at a1
; d0/d1=origin of sourceblock
; d2/d3=width and height of block to copy
; copy from blitter a1 to a2.
; d4/d5=destination XY
;
; This simple routine will assume both screens are the same width
;
; Using this blitter is a piece of piss.

	move.l #PITCH1|PIXEL16|WIDTH320|XADDINC,d7
	swap d7	
	move.l d7,BLIT_A1FLAGS	;a1 (Source) Gubbins

	move.l #PITCH1|PIXEL16|WIDTH320|XADDPIX|YADD1,d7
	swap d7
	move.l d7,BLIT_A2FLAGS	;a2 (Dest) Gubbins

	move d2,d7
	swap d7
	move d3,d7
	move.l d7,BLIT_COUNT 	;set inner and outer loop counts

	move d0,d7
	swap d7
	move d1,d7
	move.l d7,BLIT_A1PIXEL	;origin of source

	move d4,d7
	swap d7
	move d5,d7
	move.l d7,BLIT_A2PIXEL	;origin of destination

	move.l #0,BLIT_A1PIXELF


 	move.l #$00010000,BLIT_A1INC
	move.l #$0,BLIT_A1INCF

	move d2,d7
	neg d7
	swap d7
	move #1,d7
	move.l d7,BLIT_A1STEP
	move.l d7,BLIT_A2STEP		;set loop steps

	move.l a0,d7
	swap d7
	move.l d7,BLIT_A1BASE
	move.l a1,d7
	swap d7
	move.l d7,BLIT_A2BASE		;set screen window bases

	move.l #SRCEN|UPDA1|UPDA2|DSTA2|LFUFUNC_A|LFUFUNC_AN,d7
	swap d7
	move.l d7,BLIT_CMD
	bra WaitBlit

GetGirl:
;
; this transfers the CRY picture of a girlie, which some
; eejit made in a non-blitter-friendly size, into the
; middle of screen1.

	move.l #PITCH1|PIXEL16|WIDTH256|XADDINC,d7
	swap d7	
	move.l d7,BLIT_A1FLAGS	;a1 (Source) Gubbins

	move.l #PITCH1|PIXEL16|WIDTH320|XADDPIX|YADD1,d7
	swap d7
	move.l d7,BLIT_A2FLAGS	;a2 (Dest) Gubbins

	move #0,d5
	lea screen2,a0

	move.l #screen1,d7
	swap d7
	move.l d7,BLIT_A2BASE		;set screen window bases

ggrl:	move #192,d7
	swap d7
	move #1,d7
	move.l d7,BLIT_COUNT 	;set inner and outer loop counts

	move #2,d7
	swap d7
	move #0,d7
	move.l d7,BLIT_A1PIXEL	;origin of source

	move #60,d7
	swap d7
	move d5,d7
	move.l d7,BLIT_A2PIXEL	;origin of destination

	move.l #0,BLIT_A1PIXELF


 	move.l #$00010000,BLIT_A1INC
	move.l #$0,BLIT_A1INCF

	move.l a0,d7
	swap d7
	move.l d7,BLIT_A1BASE

	move.l #SRCEN|DSTA2|LFUFUNC_A|LFUFUNC_AN,d7
	swap d7
	move.l d7,BLIT_CMD
	bsr WaitBlit
	lea 400(a0),a0
	add #1,d5
	cmp #200,d5
	blt ggrl
	rts

Funky:

;	try some odd stuff

	move.l #$00010000,d6	;initial X scale
	move #0,d4		;dest line
	move.l #0,d5		;srce line
	move.l #$00010000,yinc	
	clr.l xinc

	move.l #PITCH1|PIXEL16|WIDTH320|XADDINC,d7
	swap d7	
	move.l d7,BLIT_A1FLAGS	;a1 (Source) Gubbins

	move.l #PITCH1|PIXEL16|WIDTH320|XADDPIX|YADD1,d7
	swap d7
	move.l d7,BLIT_A2FLAGS	;a2 (Dest) Gubbins

	move.l a0,d7
	swap d7
	move.l d7,BLIT_A1BASE
	move.l a1,d7
	swap d7
	move.l d7,BLIT_A2BASE		;set screen window bases



bloop:
	move d2,d7
	swap d7
	move #1,d7
	move.l d7,BLIT_COUNT 	;set inner and outer loop counts

	move xinc,d7
;	move #0,d7
	swap d7
	swap d5			;get int part of source Y
	move d5,d7
	move.l d7,BLIT_A1PIXEL	;origin of source

;	move #0,d7
	move xinc+2,d7
	swap d7
	swap d5
	move d5,d7
	move.l d7,BLIT_A1PIXELF	;fractional part of y srce origin

	move #0,d7
	swap d7
	move d4,d7
	move.l d7,BLIT_A2PIXEL	;origin of destination

	swap d6		;int part of X scale
	move d6,d7
	swap d7
	clr d7
	move.l d7,BLIT_A1INC
	swap d6		;frac part of X scale
	move d6,d7
	swap d7
	clr d7
	move.l d7,BLIT_A1INCF


	move.l #SRCEN|DSTA2|LFUFUNC_A|LFUFUNC_AN,d7
	swap d7
	move.l d7,BLIT_CMD
	bsr WaitBlit
	move.l xinc_a,d7
	sub.l #$ff,d7
	bpl xiok
	beq xiok
	neg.l d7
xiok:	sub.l d7,d6
	move.l yinc,d7
	add.l d7,d5
	move.l yinc_a,d7
	sub.l #$ff,d7
	bpl yiok
	beq yiok
	neg.l d7
yiok:	sub.l d7,yinc
	move.l xinc_a2,d7
	sub.l #$ff,d7
	bpl xiok2
	beq xiok2
	neg.l d7
xiok2:  asl.l #6,d7
	add.l d7,xinc
	add #1,d4
	cmp #200,d4
	blt bloop
 	rts

GetGpuCode: moveq #8,d0
	swap d0
	move.l d0,GPU_CTRL	;make sure it is stopped
 	lea GPU_RAM,a0	;base of GPU local RAM
	lea gpucode,a1		;where the linker includes GPU code
	move.l (a1)+,d0		;throw away first long
	move.l (a1)+,d0		;length of prog in bytes
	asr.l #2,d0		;convert to longwords
getgpu: move.l (a1)+,(a0)+
	dbra d0,getgpu		;copy the code in
	rts


LeonardsMandy:
	INBUF		equ	GPU_RAM+$fc0

	WIDTH		equ	320
	HEIGHT		equ	200

; The X numbers are shifted right by 13 before use
; These numbers are in units of 1/8192

; The commented out numbers do this SciAm cover
	XINC		equ	1
	XSTART		equ	$fffffa86

;	XSTART		equ	((-2)<<13)
;	XINC		equ	((10<<11)/WIDTH)

;	XSTART		equ	$ffffec1a
;	XINC		equ	1

; The Y numbers are shifted right by 13 before use
; These numbers are in units of 1/8192

; The commented out numbers do this SciAm cover
	YINC		equ	1
	YSTART		equ	$ffffde9a	

;	YSTART		equ	((-19)<<9)
;	YINC		equ	((6<<12)/WIDTH)

;	YSTART		equ	$ffffea00
;	YINC		equ	1

Mandle:

	move.l #-1,GPU_RAM+$fd8	;set GPU prog to mandy inner loop
	move.l	#0,jx
	move.l	#0,jy

	movea.l	#screen1,a1

	move.l	#YSTART,ypos	; Initialize y position

	move.l	#HEIGHT-1,d2

	movea.l	#INBUF+8,a0

	move.l	jx,d0
	swap	d0
	move.l	d0,(a0)+

	move.l	jy,d0
	swap	d0
	move.l	d0,(a0)

outer:
	movea.l	#INBUF+4,a0

	move.l	ypos,d0
	swap	d0
	move.l	d0,(a0)

	move.l	#WIDTH-1,d1
	move.l	#XSTART,xpos	; Initialize x position

inner:
	movea.l	#INBUF,a0

	move.l	xpos,d0
	swap	d0
	move.l	d0,(a0)

	movea.l	#gpu_sem,a0
	move.l	#0,d0
	move.l	d0,(a0)

	move.l	#$30000040,$00d02110	; GPU Program counter gets $403000

	move.l	#$00110000,$00d02114	; Set the GPU going

wait:	move.l	(a0),d0
	beq	wait
	
;	swap	d0
	move.b	d0,(a1)+
;	move.b #$80,(a1)+

	add.l	#XINC,xpos

	dbra	d1,inner


	add.l	#YINC,ypos

	dbra	d2,outer
	move.l #0,GPU_RAM+$fd8

	rts


*----------- thangs

.even
.data

		dcb.l	32,0
list1:	dcb.l	1024,0

		dcb.l	32,0
list2:	dcb.l	1024,0

blist: dc.l list1
dlist: dc.l list2

nbeasties: dc.w 12
beasties: dcb.l 286,0

 	dcb.l 80,0
stack: dc.l 0

testdata: dc.l $00ff0000,$00000000
	  dc.l $ffff0000,$00000000
	  dc.l $00ff0000,$00000000
	  dc.l $00ff0000,$00000000
	  dc.l $00ff0000,$00000000
	  dc.l $00ff0000,$00000000
	  dc.l $00ffffff,$ffffffff
	  dc.l $00fff0ff,$ffff00ff
	  dc.l $00ffffff,$ffff0000
	  dc.l $00ffffff,$ffff0000
	  dc.l $00ffff00,$00ff0000
	  dc.l $00ff0000,$00ff0000
	  dc.l $00ff0000,$00ff0000
	  dc.l $00ff0000,$00ff0000
	  dc.l $00ff0000,$00ff0000
	  dc.l $ffff0000,$ffff0000


pong1: dc.l $ffff0000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ff000000,00000000
	dc.l $ffff0000,00000000

	dc.l $ff000000,00000000
	dc.l 0000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000
	dc.l 000000,00000000
	dc.l $ff000000,00000000


midobj: dc.l 0

pbx: dc.w 160
pvx: dc.w 2
pby: dc.w 266
pvy: dc.w 1
bat1: dc.w 220
bat2: dc.w 220

counter: dc.w 0
pointer: dc.l 0
cscreen: dc.l screen2
dscreen: dc.l screen3
rot_scale: dc.l 0
rot_scale_add: dc.l 0
rot_scale_grav: dc.l 0

yinc: dc.l 0
yinc_a: dc.l 0
xinc_a: dc.l 0
xinc: dc.l 0
xinc_a2: dc.l 0

p2inc: dc.w 1

grad: dc.w 8
grad2: dc.w 4
sync: dc.w 0
gpu_data: dc.w $0101
screen_ready: dc.w 0
pointer2: dc.w 0

grad_source: dc.l 0


sws1: dc.l 0
swp1: dc.l 0
sws2: dc.l 0
swp2: dc.l 0
p1c: dc.w 0
p2c: dc.w 0
p1a: dc.w 0
p2a: dc.w 0
yi: dc.w 0
yia: dc.w 0


step1: dc.l 0
step2: dc.l 0
step3: dc.l 0
step4: dc.l 0
step5: dc.l 0
step6: dc.l 0
ud: dc.w 0
db_on: dc.w 0
cpx: dc.w 0
cpy: dc.w 0
cpc: dc.w 0

pointx: dc.w 0
pointy: dc.w 0
elist: dc.l 0
gscreen: dc.l 0
;tx_pos: dc.l 0
;tx_vel: dc.l $2a00
;ty_pos: dc.l 0
;ty_vel: dc.l $3b00

tx_pos: dc.l 0
tx_vel: dc.l $12a00
ty_pos: dc.l 0
ty_vel: dc.l $fb00
mainloop_count: dc.w 0
mainloop_routine: dc.l 0
g1i: dc.w 0
g2i: dc.w 0
gpui: dc.w 1
rotators: dcb.w 256,0
zoo: dc.w 0
pstab: dcb.l 512,0
psptr: dc.l 0
pscou: dc.w 0
psptr2: dc.l 0
pscou2: dc.w 0
sptr: dc.w 0
sptrr: dc.w 0
sptra: dc.w 0
sptrs: dc.w 0
imsk: dc.w 0
scaleshift: dc.w 1
kwok: dc.l 0
tz_pos: dc.w 0
tz_vel: dc.w 4
tzp: dc.w 0
xpos:	dc.l	1
ypos:	dc.l	1
jx:	dc.l	1
jy:	dc.l	1
od_type: dc.l cro_x
pong_on: dc.w 1
_demo: dc.w 0
frames: dc.w 0
ObTypes: dc.w $50,199,4,0	;320x200, 16bit
	dc.w $28,99,4,0		;160x100
	dc.w $10,99,4,0		;64x100, robot object
gpucode:
