',13,10,0

; word align everything
	ds.w 0

; this is the init structure that out RTF_AUTOINIT told exec to look for
Init:
	dc.l base_SIZEOF	; size of library base data space
	dc.l funcTable		; pointer to the function initializers
	dc.l dataTable		; pointer to the data initializers
	dc.l initRoutine	; routine to run

; here we have the function table.  it, of course, starts with the standard
; library routines like Open, etc.
funcTable:
	dc.l Open
	dc.l Close
	dc.l Expunge
	dc.l Null		; reserved routine

; my library routines
	dc.l GetFirstIndex
	dc.l GetNextIndex
	dc.l FreeIndex
	dc.l GetCreationStamp

; end of library function list
	dc.l -1

; static data structures initilization table
dataTable:
	INITBYTE LN_TYPE,NT_LIBRARY
	INITLONG LN_NAME,AutoDocName
	INITBYTE LIB_FLAGS,LIBF_SUMUSED|LIBF_CHANGED
	INITWORD LIB_VERSION,VERSION
	INITWORD LIB_REVISION,REVISION
	INITLONG LIB_IDSTRING,idString
	dc.l 0

; after the library has been allocated this next routine gets called.
; d0 = library's pointer, a0 = segment list
;
; returning non-zero means ok to link library into system list
initRoutine:
	move.l	a5,-(sp)
	move.l	d0,a5		; make library base easy to get at

	move.l	a6,base_SysLib(a5)	; save pointer to exec
	move.l	a0,base_SegList(a5)	; save pointer to loaded code

	move.l	(sp)+,a5
	rts

; here we have the library interface Open routine.  returns library
; pointer or null if it fails (which it never will)
Open:
	addq.w	#1,LIB_OPENCNT(a6)		; say another opened us
	bclr	#LIBB_DELEXP,base_Flags(a6)	; prevent delayed expunges

	move.l	a6,d0
	rts

; this is the library interface Close routine.  returns seglist if no
; more opencnt and delayed expunge waiting, otherwise return null.
Close:
	moveq	#0,d0
	subq.w	#1,LIB_OPENCNT(A6)		; one less open now
	bne	1$				; still got someone around

	btst	#LIBB_DELEXP,base_Flags(a6)	; is delayed expunge pending?
	beq.s	1$

	bsr	Expunge				; yes, so do it
1$:
	rts

; this is the library interface Expunge routine.
Expunge:
	movem.l	d2/a5/a6,-(sp)
	move.l	a6,a5
	move.l	base_SysLib(a5),a6		; get exec pointer

	tst.w	LIB_OPENCNT(a5)			; anyone have us open?
	beq.s	1$

	bset	#LIBB_DELEXP,base_Flags(a5)	; still open so set delayed exp
	moveq	#0,d0
	bra.s	Expunge_End

1$:	; no one left so dump this sucker!
	move.l	base_SegList(a5),d2

	move.l	a5,a1
	jsr	_LVORemove(a6)	; unlink from library list

	moveq	#0,d0
	move.l	a5,a1
	move.w	LIB_NEGSIZE(a5),d0

	sub.l	d0,a1
	add.w	LIB_POSSIZE(a5),d0

	jsr	_LVOFreeMem(a6)	; free the mem used by cawlib itself

	move.l	d2,d0	; put seglist as return value for success

Expunge_End:
	movem.l	(sp)+,d2/a5/a6
	rts

Null:
	moveq	#0,d0	; reserved for future expansion I guess.
	rts		; MUST ALWAYS RETURN NULL FOR FUTURE COMPATIBILITY!

; --------------------------------------------------------------------------
; here we have the first library routine.  this one looks for an occurance
; of a function name in the index list.  it takes a pointer to the needed
; function name as its only argument in register a0.

GetFirstIndex:
	movem.l	a2-a3,-(sp)
	movea.l	a0,a3			; save pointer to function name
	lea	FirstIndexNode(pc),a2	; get pointer to first index node

1$	move.l	a2,d0			; test if no more nodes
	beq.s	4$			; yes so exit with zero in d0

	movea.l	a3,a0
	movea.l	12(a2),a1
	bsr	StrCmp			; compare function against index

	tst.l	d0			; check if equal
	bne.s	2$

	lea	12(a2),a0		; yes so return index data node
	move.l	a0,d0
	bra.s	4$

2$	tst.l	d0
	ble.s	3$

	movea.l	(a2),a2			; lexically greater so go up
	bra.s	1$

3$	movea.l	4(a2),a2		; lexically lesser so go down
	bra.s	1$

4$	movem.l	(sp)+,a2-a3		; all done so clean up stack and
	rts				; go home

; --------------------------------------------------------------------------
; this function will return the next node matching a function name.  it
; takes a pointer to an IndexData as its only argument in register a0.

GetNextIndex:
	suba.l	#4,a0
	movea.l	(a0),a1
	move.l	a1,d0
	bne.s	1$

	rts			; no more nodes so return zero

1$	lea	4(a1),a0	; got another node so return its indexdata
	move.l	a0,d0
	rts

; --------------------------------------------------------------------------
; this routine does nothing in this version of the library.  it is provided
; for future expansion.  It takes as its argument a pointer in a0 to an
; IndexData structure returned by GetFirstIndex/GetNextIndex

FreeIndex:
	moveq	#0,d0
	rts

; --------------------------------------------------------------------------
; this routine will return a date stamp that holds the index's creation date
; and time.  it takes as its only arguement a vector to three long words to
; place the stamp in, much like the AmigaDOS DateStamp() function returns
; the current system time.
GetCreationStamp:
	lea	CreationStamp(pc),a0
	movea.l	d1,a1
	moveq	#2,d0
1$	move.l	(a0)+,(a1)+
	dbf	d0,1$
	rts

; --------------------------------------------------------------------------
; here we have the string compare function used by GetFirstIndex.  it takes
; pointers to the two strings to be compared in registers a0 and a1.

StrCmp:
	moveq	#0,d0
	moveq	#0,d1

1$	move.b	(a0)+,d0
	move.b	(a1)+,d1

	cmpi.b	#'a',d0			; check if d0 needs case change
	blt.s	2$
	cmpi.b	#'z',d0
	bgt.s	2$
	subi.b	#'a'-'A',d0

2$	cmpi.b	#'a',d1			; check if d1 needs case change
	blt.s	3$
	cmpi.b	#'z',d1
	bgt.s	3$
	subi.b	#'a'-'A',d1

3$	sub.l	d1,d0			; do a compare
	bne.s	4$
	tst.b	d1			; check if more to do
	bne.s	1$

4$	rts

; --------------------------------------------------------------------------
; here we have the actual index data tree
