***************************************************************************

; bmp.datatype v0.1 - 20/05/95 by Gunther Nikl - first version

***************************************************************************

; include stuff

		include	exec/types.i
		include	exec/resident.i
		include	exec/libraries.i
		include	exec/initializers.i
		include	lvo30/exec_lib.i
		include	lvo30/utility_lib.i
		include	lvo30/graphics_lib.i
		include	lvo30/intuition_lib.i

; import

		XREF	_GetBMP

; specific defines

BMPVER		equ	40
BMPREV		equ	4

need_mulsi3	set	1

; macro stuff

CALL		MACRO
		move.l	\2,a6
		jsr	_LVO\1(a6)
		ENDM

RECALL		MACRO
		jsr	_LVO\1(a6)
		ENDM

ADDCMD		macro
		dc.w	\1-FuncTab
		endm

; class base

	STRUCTURE ClassBase,36

	 ULONG	cb_SegList
	 ULONG	cb_SysBase
	 ULONG	cb_DosBase
	 ULONG	cb_IntBase
	 ULONG	cb_GfxBase
	 ULONG	cb_UtilityBase
	 ULONG	cb_DataTypesBase
	 ULONG	cb_SuperClassBase
	 ULONG	cb_BMPClass
	 STRUCT	cb_Lock,48

	LABEL cb_SIZEOF

LastBase	equ	cb_SuperClassBase

***************************************************************************

start		moveq	#-1,d0
		rts

***************************************************************************

RomTag		dc.w	RTC_MATCHWORD
		dc.l	RomTag
		dc.l	EndTag
		dc.b	RTF_AUTOINIT
		dc.b	BMPVER
		dc.b	NT_LIBRARY
		dc.b	0
		dc.l	LibName
		dc.l	IdString
		dc.l	InitTab
EndTag

;--------------------------------------------------------------------------

LibName		dc.b	'bmp.datatype',0
IdString	dc.b	'bmp 40.4 (11.8.95) by Gunther Nikl',13,10,0
DosName		dc.b	'dos.library',0
IntName		dc.b	'intuition.library',0
GfxName		dc.b	'graphics.library',0
UtilityName	dc.b	'utility.library',0
DataTypesName	dc.b	'datatypes.library',0
SuperClassName	dc.b	'datatypes/'
PicDTClassName	dc.b	'picture.datatype',0

;--------------------------------------------------------------------------

		cnop	0,4

InitTab		dc.l	cb_SIZEOF
		dc.l	FuncTab
		dc.l	ResInfo
		dc.l	InitFunc

;--------------------------------------------------------------------------

FuncTab		dc.w	-1
		ADDCMD	LibOpen
		ADDCMD	LibClose
		ADDCMD	LibExpunge
		ADDCMD	LibExtFunc
		ADDCMD	GetBMPEngine
		dc.w	-1

;--------------------------------------------------------------------------

ResInfo		INITBYTE LN_TYPE,NT_LIBRARY
		INITLONG LN_NAME,LibName
		INITBYTE LIB_FLAGS,(LIBF_SUMUSED!LIBF_CHANGED)
		INITWORD LIB_VERSION,BMPVER
		INITWORD LIB_REVISION,BMPREV
		INITLONG LIB_IDSTRING,IdString
		dc.w 0

***************************************************************************

		cnop	0,4

InitFunc	move.l	a5,-(sp)
		suba.l	a5,a5
		cmp.w	#39,20(a6)
		bcs.s	1$			; wrong OS (not 3.x !)
		move.l	d0,a5
		move.l	a0,cb_SegList(a5)	; save seglist
		move.l	a6,cb_SysBase(a5)	; cache SysBase (speed!)
		lea	cb_Lock(a5),a0
		RECALL	InitSemaphore
1$		move.l	a5,d0			; return LibBase (or NULL)
		move.l	(sp)+,a5
		rts

;--------------------------------------------------------------------------

OpenLibs	lea	DosName(pc),a1		; open all libraries
		moveq	#cb_DosBase,d2
		bsr.s	2$
		beq.s	1$			; no dos v39+!
		lea	IntName(pc),a1
		moveq	#cb_IntBase,d2
		bsr.s	2$
		beq.s	1$			; no intuition v39+!
		lea	GfxName(pc),a1
		moveq	#cb_GfxBase,d2
		bsr.s	2$
		beq.s	1$			; no graphics v39+!
		lea	UtilityName(pc),a1
		moveq	#cb_UtilityBase,d2
		bsr.s	2$
		beq.s	1$			; no utility v39+!
		lea	DataTypesName(pc),a1
		moveq	#cb_DataTypesBase,d2
		bsr.s	2$
		beq.s	1$			; no datatypes v39+!
		lea	SuperClassName(pc),a1
		moveq	#cb_SuperClassBase,d2
2$		moveq	#39,d0
		RECALL	OpenLibrary
		move.l	d0,0(a5,d2.w)		; store library base
1$		rts

LibOpen		movem.l	d2/a2/a5/a6,-(sp)
		move.l	a6,a5
		addq.w	#1,32(a5)		; one more user
		and.b	#$f7,14(a5)
		move.l	a5,d2
		cmp.w	#1,32(a5)		; first opener?
		bne.s	1$
		lea	cb_Lock(a5),a0
		CALL	ObtainSemaphore,cb_SysBase(a5)
		bsr.s	OpenLibs
		beq.s	3$			; failed...
		move.l	a6,-(sp)
		moveq	#0,d0
		moveq	#0,d1
		lea	LibName(pc),a0
		lea	PicDTClassName(pc),a1
		suba.l	a2,a2
		CALL	MakeClass,cb_IntBase(a5)
		move.l	d0,cb_BMPClass(a5)
		beq.s	4$			; no class...
		move.l	d0,a0
		lea	BMPDispatch(pc),a1
		move.l	a1,8(a0)
		move.l	a5,36(a0)
		RECALL	AddClass		; make it public
		move.l	a5,d2
4$		move.l	(sp)+,a6
		bne.s	2$			; leave for good
3$		bsr.s	CloseLibs
		subq.w	#1,32(a5)
		moveq	#0,d2
2$		lea	cb_Lock(a5),a0
		RECALL	ReleaseSemaphore	; we are through
1$		move.l	d2,d0
		movem.l	(sp)+,d2/a2/a5/a6
		rts

;--------------------------------------------------------------------------

LibClose	movem.l	d2/a5/a6,-(sp)
		move.l	a6,a5
		moveq	#0,d0			; do not unload
		tst.w	32(a5)
		beq.s	3$
		subq.w	#1,32(a5)		; one less user
		bne.s	1$
3$		lea	cb_Lock(a5),a0
		CALL	ObtainSemaphore,cb_SysBase(a5)
		move.l	cb_BMPClass(a5),d0	; class created?
		beq.s	2$
		move.l	a6,-(sp)
		move.l	d0,a0
		CALL	FreeClass,cb_IntBase(a5) ; free it
		clr.l	cb_BMPClass(a5)
		move.l	(sp)+,a6
2$		bsr.s	CloseLibs		; close all libs
		lea	cb_Lock(a5),a0
		RECALL	ReleaseSemaphore	; free semaphore here...
		moveq	#0,d0
		btst	#3,14(a5)
		beq.s	1$			; do not expunge!
		move.l	a5,a6
		bsr.s	LibExpunge		; remove library
1$		movem.l	(sp)+,d2/a5/a6
		rts

CloseLibs	moveq	#LastBase-cb_SysBase,d2
2$		move.l	cb_SysBase(a5,d2.w),d0
		beq.s	1$			; no library to close
		move.l	d0,a1
		RECALL	CloseLibrary
		clr.l	cb_SysBase(a5,d2.w)	; clear entry
1$		subq.w	#4,d2
		bne.s	2$			; not ready
		rts

;--------------------------------------------------------------------------

LibExpunge	movem.l	a2/a5/a6,-(sp)
		move.l	a6,a5
		suba.l	a2,a2
		or.b	#8,14(a5)		; set LIBF_DELEXP
		tst.w	32(a5)
		bne.s	1$			; still in use...
		move.l	cb_SysBase(a5),a6
		move.l	cb_SegList(a5),a2	; get seglist
		move.l	a5,a1
		RECALL	Remove
		move.l	a5,a1
		moveq	#0,d0
		move.w	16(a5),d0
		suba.l	d0,a1
		add.w	18(a5),d0
		RECALL	FreeMem
1$		move.l	a2,d0			; return SegList (or NULL)
		movem.l	(sp)+,a2/a5/a6
		rts

;--------------------------------------------------------------------------

LibExtFunc	moveq	#0,d0			; reserved library entry
		rts

;--------------------------------------------------------------------------

GetBMPEngine	move.l	cb_BMPClass(a6),d0	; return class pointer
		rts

***************************************************************************

; a0 -> a5 = class
; a2       = object
; a1 -> a3 = msg

BMPDispatch	movem.l	a2-a5,-(sp)
		move.l	a0,a5			; save class
		move.l	a1,a3			; save message
		bsr.s	_DoSuperMethod
		move.l	d0,a2
		move.l	a2,d0
		beq.s	1$			; NULL -> leave
		cmpi.l	#$101,0(a3)
		bne.s	1$			; not OM_NEW !
		move.l	4(a3),-(sp)		; ops_AttrList
		move.l	a2,-(sp)
		move.l	a5,-(sp)
		move.l	36(a5),a4
		jsr	_GetBMP
		lea	12(sp),sp
		tst.l	d0
		bne.s	1$			; all ok !
		move.l	a5,a0
		pea	$102
		move.l	sp,a1
		bsr.s	_CoerceMethod		; dispose object
		addq.w	#4,sp
		suba.l	a2,a2			; NULL
1$		move.l	a2,d0
		movem.l	(sp)+,a2-a5
		rts

_DoSuperMethod	move.l	24(a0),a0		; boopsi support
_CoerceMethod	move.l	8(a0),-(sp)
		rts

;--------------------------------------------------------------------------

	IFD need_mulsi3

		XDEF	___mulsi3

___mulsi3:	movem.l	4(sp),d0/d1
		move.l	cb_UtilityBase(a4),a0
		jmp	_LVOSMult32(a0)

	ENDC

		end
