;***********************************************************************
;* FreeResource.a                                                      *
;* ©1996 M.Bethke                                                      *
;* Used in the rtFreeResources program and to show use of rt_ResList   *
;***********************************************************************


	include "exec/lists.i"

LIBCALL MACRO
	jsr	_LVO\1(a6)
	ENDM


	STRUCTURE RESLIST,MLH_SIZE
	WORD	RL_ALLOC	;allocation function offset
	WORD	RL_FREE	;deallocation function offset
	CPTR	RL_LIB	;library name for these offsets
	APTR	RL_POOL	;memory pool for nodes
	WORD	RL_IDOFFSET	;struct offset for resource description
	BYTE	RL_FREEREG	;register for deallocation function
	BYTE	PAD	;pad to word-alignment
	LABEL	RL_SIZE



	XDEF _FreeResource

_LVOOpenLibrary		equ -552
_LVOCloseLibrary	equ -414

	SECTION FreeResoure,CODE


;******************************************************************
;Inputs: a3: Pointer to resource
;        a4: Pointer to resourcelist
;Output: d0: Success
;******************************************************************
_FreeResource:
	movem.l	d1-d7/a0-a2/a5-a6,-(sp)
	move.l	4.w,a6
	move.l	RL_LIB(a4),a1		;get library name
	move.l	#0,d0		;we *do* have the correct version :)
	LIBCALL	OpenLibrary		;open specified library
	tst.l	d0
	beq.s	NoLibrary		;exit if failed
	pea	LibcallDone(pc)		;push address to continue at after libcall
	move.l	d0,-(sp)		;push libbase again for the actual call
	move.l	d0,a6		;for later libcall

	move.w	RL_FREE(a4),d1		;get free offset
	ext.l	d1
	add.l	d1,(sp)		;add to librarybase for jump destination
	pea	DoLibJump(pc)		;push return address for jumptable
	moveq	#0,d1
	move.b	RL_FREEREG(a4),d1	;get register code for free()
	lea	RegJumps(pc),a0		;load jumptable start
	lsl.w	#2,d1		;extend to long offset
	move.l	0(a0,d1.w),a0		;retrieve jump address
	jmp	(a0)		;load correct register
DoLibJump:				;this is the next return address on stack!
	rts			;pops LibBase+LVO fromstack and jumps there
LibcallDone:				;the library's final rts gets us here
	move.w	#-1,-(sp)		;returncode=TRUE
CloseLib:
	move.l	a6,a1
	move.l	4.w,a6
	LIBCALL	CloseLibrary	
	moveq	#1,d0
Finish:
	move.w	(sp)+,d0
	ext.l	d0
	movem.l	(sp)+,d1-d7/a0-a2/a5-a6
	rts
NoLibrary:
	clr.w	-(sp)		;returncode=FALSE
	bra.s	Finish


UseD0:	move.l	a3,d0
	rts
UseD1:	move.l	a3,d1
	rts
UseD2:	move.l	a3,d2
	rts
UseD3:	move.l	a3,d3
	rts
UseD4:	move.l	a3,d4
	rts
UseD5:	move.l	a3,d5
	rts
UseD6:	move.l	a3,d6
	rts
UseD7:	move.l	a3,d7
	rts
UseA0:	move.l	a3,a0
	rts
UseA1:	move.l	a3,a1
	rts
UseA2:	move.l	a3,a2
	rts
UseA3:	rts		;no need to move anything :-)
UseA4:	move.l	a3,a4
	rts
UseA5:	move.l	a3,a5
UseA6:
UseA7:	lea	12(sp),sp	;should never happen!
	clr.w	-(sp)	;returncode=FALSE
	bra.s	CloseLib


RegJumps:	dc.l	UseD0,UseD1,UseD2,UseD3,UseD4,UseD5,UseD6,UseD7
	dc.l	UseA0,UseA1,UseA2,UseA3,UseA4,UseA5,UseA6,UseA7

	END
