 ; Amiga Interrupts. By Ian Potts. (c)1989 CoolSoft.
 ; Listing 1. Example of AddIntServer

 ; Assembled with DevPac V2.08 By HiSoft Ltd.


		opt	d-,o+,ow-	;no debug, optimise on

		incdir		"rad:include/"
		include		"exec/exec_lib.i"	;exec
		include		"graphics/graphics_lib.i"	;graphics
		include		"graphics/view.i"	;for view stuff
		include		"graphics/sprite.i"	;for sprite stuff
		include		"intuition/intuition_lib.i"	;intuition
		include		"hardware/intbits.i	;int bit definitions
		include		"exec/interrupts.i"	;server structure

		include		"misc/easystart.i"

		moveq		#31,D0		;open graphics library
		lea		graflib(pc),a1
		CALLEXEC	OpenLibrary
		move.l		d0,_GfxBase
		moveq		#31,d0		;open intuition library
		lea		intuilib(pc),a1
		CALLEXEC	OpenLibrary
		move.l		d0,_IntuitionBase

		CALLINT		ViewAddress	;get address of View
		move.l		d0,a0
		move.l		v_ViewPort(a0),viewport	;and first viewport

		bsr		initsprite	;get a hardware sprite
		tst.l		d0		;successful?
		bne.s		exit		;no, sigh
				
		move.b		#10,alldone	;bounce sprite 10 times
		move.l		#myinterrupt,myint+IS_CODE
		clr.l		myint+IS_DATA	;set up our
		clr.b		myint+LN_PRI	;server structure
		lea		myint(pc),a1
		move.l		#INTB_VERTB,d0	;and add it to the Vertical
		CALLEXEC	AddIntServer	;Blank chain

snooze:		cmpi.b		#0,alldone	;wait until bounced
		bne.s		snooze		;10 times

		lea		myint(pc),a1	;remove our server
		move.l		#INTB_VERTB,d0	;from the chain
		CALLEXEC	RemIntServer
		clr.l		d0		;free up our sprite
		move.w		mysprite+ss_num,d0
		CALLGRAF	FreeSprite
exit:		move.l		_IntuitionBase(pc),a1	;close the libraries
		CALLEXEC	CloseLibrary
		move.l		_GfxBase(pc),a1
		CALLEXEC	CloseLibrary
		rts					;and exit


myinterrupt:	movem.l		d2-d7/a2-a4/a6,-(a7)	;save registers
		bsr.s		movesprite		;move the sprite
		movem.l		(a7)+,d2-d7/a2-a4/a6	;restore registers
		clr.l		d0			;let the next server
		rts					;in the chain run

movesprite:	cmpi.b		#0,alldone		;bounced 10 times?
		beq.s		movespriteexit		;yes so skip
		subi.b		#1,spritedelay		;moved 160 pixels?
		bne.s		movesprite1		;no, keep moving
		move.b		#160,spritedelay	;yes, reset delay
		sub.b		#1,alldone		;bounced once more
		eori.b		#$fe,spritedelta	;change direction
movesprite1:	move.l		viewport(pc),a0		;move the sprite
		lea		mysprite(pc),a1
		move.l		#160,d0
		clr.l		d1
		move.b		spritey(pc),d1
		add.b		spritedelta(pc),d1	;up/down 1 pixel
		move.b		d1,spritey
		CALLGRAF	MoveSprite
movespriteexit:	rts

initsprite:	lea		mysprite(pc),a0		;get a simple sprite
		moveq		#-1,d0	;any sprite
		CALLGRAF	GetSprite
		cmp.l		#-1,d0			;none free?
		beq.s		initspriteexit		;oh well, exit
		move.w		#10,mysprite+ss_height	;height is 10 pixels
		lea		spriteimage,a2		;point to our picture
		lea		mysprite(pc),a1
		move.l		viewport(pc),a0
		CALLGRAF	ChangeSprite		;change sprite shape
		move.b		#20,spritey		;set y position
		move.b		#1,spritedelta		;direction
		move.b		#160,spritedelay	;and delay
		clr.l		d0			;successful
initspriteexit:	rts

mysprite:	ds.b		ss_SIZEOF	;simple sprite structure
		even
spritey:	dc.b		0		;y position
spritedelta:	dc.b		0		;direction
spritedelay:	dc.b		0		;number of pixels to move
alldone:	dc.b		0		;number of bounces left
viewport:	dc.l		0		;address of viewport
myint:		ds.b		IS_SIZE		;interrupt server structure
		even
_GfxBase:	dc.l		0
_IntuitionBase:	dc.l		0
graflib:	GRAFNAME
intuilib:	INTNAME

		SECTION		SpriteData,DATA_C	;our sprite picture
							;in CHIP RAM!

spriteimage:	dc.w		0,0	;position control data
		dc.w		384,384,960,960,960,960,65535,0,0,65535
		dc.w		0,65535,65535,0,960,960,960,960,384,384
		dc.w		$ffff,$ff7f

