;
; sprinkle.s
;
; Handling of linked sprite areas (MDW)
;
;  1995-1998 Straylight
;

;----- Licensing note -------------------------------------------------------
;
; Sprinkle is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2, or (at your option)
; any later version.
;
; Sprinkle is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with Sprinkle.  If not, write to the Free Software Foundation,
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

;----- Standard header ------------------------------------------------------

		GET	libs:header
		GET	libs:swis

		GET	libs:stream

;----- External dependencies ------------------------------------------------

		IMPORT	version

;----- Main code ------------------------------------------------------------

		AREA	|!!!Module$$Header|,CODE,READONLY

		DCD	0
		DCD	sl__init
		DCD	sl__final
		DCD	0
		DCD	sl__name
		DCD	version
		DCD	0

sl__name	DCB	"Sprinkle",0

;----- Module header --------------------------------------------------------

		AREA	|Module$$Code|,CODE,READONLY

; --- sl__init ---
;
; On entry:	--
;
; On exit:	R0-R6 corrupted
;
; Use:		Initialises our module.

sl__init	ROUT

		STMFD	R13!,{R14}		;Save the link register
		MOV	R0,#&1F			;SpriteV's vector number
		ADR	R1,sl__spriteV		;Point to my handler routine
		MOV	R2,#0			;No workspace required
		SWI	XOS_Claim		;Try to claim the vector
		LDMFD	R13!,{PC}		;Return with that status

		LTORG

; --- sl__final ---
;
; On entry:	--
;
; On exit:	R0-R6 corrupted
;
; Use:		Finalises our module when it's not needed any more.

sl__final	ROUT

		STMFD	R13!,{R14}		;Save the link register
		MOV	R0,#&1F			;SpriteV's vector number
		ADR	R1,sl__spriteV		;Point to the handler routine
		MOV	R2,#0			;No workspace passed
		SWI	XOS_Release		;Release the vector
		LDMFD	R13!,{PC}^		;Return without hassle

		LTORG

; --- sl__spriteV ---
;
; On entry:	R0 == reason code
;		R1 == pointer to sprite area, normally
;
; On exit:	As for OS_SpriteOp
;
; Use:		Catches calls to OS_SpriteOp, to allow linked sprite areas.

sl__spriteV	ROUT

		TST	R0,#&100		;Is it named/user area?
		MOVEQS	PC,R14			;No -- pass on the call then

		STMFD	R13!,{R10,R14}		;Save some registers

		; --- See if this call needs a sprite area in R1 ---

		AND	R14,R0,#&300		;Get the magic extra bits
		CMP	R14,#&100		;Using a user area?
		LDMNEFD	R13!,{R10,PC}^		;No -- then do nothing

		BIC	R14,R0,#&300		;Clear the magic bits
		CMP	R14,#8			;Does call need area in R1?
		LDMCCFD	R13!,{R10,PC}^		;No -- do nothing then

		; --- See if the sprite area is linked ---

10sl__spriteV	LDR	R14,[R1,#8]		;Load offset to first sprite
		CMP	R14,#24			;Enough space for link?
		LDMCCFD	R13!,{R10,PC}^		;No -- do nothing then

		LDR	R10,[R1,#16]		;Load first word of link
		LDR	R14,sl__magic		;Load the magic word
		CMP	R10,R14			;Do these match?
		LDMNEFD	R13!,{R10,PC}^		;No -- do nothing then

		; --- Now worked it out then ---

		LDR	R10,[R1,#20]		;Load the link pointer
		CMP	R10,#0			;End of the list?
		LDMEQFD	R13!,{R10,PC}^		;Yes -- do nothing then

		; --- Now call OS_SpriteOp and post-process ---

		STMFD	R13!,{R0,R10}		;Save reason code and link
		MOV	R14,PC			;Get PC and flags in R14
		ADD	R14,R14,#12		;Point to postprocess code
		STMFD	R13!,{R14}		;Save those registers away
		ADD	R14,R13,#12		;Skip over stacked registers
		LDMIA	R14,{R10,PC}^		;And call OS_SpriteOp

		; --- Returned from OS_SpriteOp ---

		LDMVSFD	R13!,{R0,R1}		;If failed, load link pointer
		BVS	%10sl__spriteV		;And loop backwards to next
		ADD	R13,R13,#8		;Point to old stack frame
		LDMFD	R13!,{R10,R14,PC}^	;And claim the call

sl__magic	DCB	"SPLK"

		LTORG

;----- That's all, folks ----------------------------------------------------

		END
