
*	Maxon C++:
*	Library-Modul "memory"
*	Jens Gelhar 24.03.96

	xdef	_malloc,malloc__Ui
	xdef	_calloc,calloc__UiUi
	xdef	_free,free__Pv
	xdef	FreeStore__HashTable,___MEMFLAGS
	xdef	_EXIT_1_Please_free_Allocated_Store
	xdef	set_new_handler__PFvp,_set_new_handler
	xdef	blocksize_a2_d2

	xref	uintmult,exit__i,_errno

ExecBase	= 4

AllocMem	= -198
FreeMem		= -210

HushAnz		= 64


_calloc:
calloc__UiUi:	; Stack-Parameter: (unsigned num, unsigned size)
	move.l 8(a7),d0
	cmp.l #2,d0
	bls.b noalign
	addq.l #1,d0
	and.w #$FFFE,d0
noalign:	move.l d1,-(a7)
	move.l 8(a7),d1
	jsr uintmult
	move.l (a7)+,d1
	move.l d0,-(a7)
	jsr _malloc(pc)
	addq.l #4,a7
	rts

memhush: ; Aus Adresse d0 Hashnummer*4 machen
	lsr.l #4,d0
	and.l #4*(HushAnz-1),d0
	rts

blocksize_a2_d2:
	move.l	-4(a2),d2
	subq.l	#4,d2
	rts

_malloc:
malloc__Ui:	; Stack-Parameter: (unsigned)
	move.l 4(a7),d0
	addq.l #3,d0
	and.w #$FFFC,d0
	addq.l #8,d0
	movem.l d2/a6,-(a7)
	move.l ExecBase.w,a6
	move.l ___MEMFLAGS(pc),d1
	move.l d0,-(a7)
	jsr AllocMem(a6)
	move.l (a7)+,d1
	tst.l d0
	beq.b memfail
	move.l d0,a0
	bsr.b memhush
	lea	FreeStore__HashTable,a1
	add.l	d0,a1
	move.l (a1),(a0)
	move.l a0,(a1)
	move.l d1,4(a0)
	move.l a0,d0
	addq.l #8,d0
	bra.b memret
memfail:	move.l NewHandler(pc),d0
	beq.b memret
	move.l d0,a6
	jsr (a6)
	movem.l (a7)+,d2/a6
	bra.b _malloc           ; nochmal versuchen
memret:	movem.l (a7)+,d2/a6
	rts

set_new_handler__PFvp:
_set_new_handler:
	move.l NewHandler(pc),d0
	move.l 4(a7),NewHandler
	rts

NewHandler:	dc.l 0


_free:
free__Pv: ; Stack-Parameter: Zeiger
	movem.l d0-d2/a0/a1/a6,-(a7)
	move.l 6*4+4(a7),d0
	beq.b freret
	subq.l #8,d0
	move.l d0,a1
	bsr memhush
	lea	FreeStore__HashTable,a0
	add.l	d0,a0
freLoop: move.l (a0),d1
	beq.b freIndirect
	cmp.l a1,d1
	beq.b freFound
	move.l d1,a0
	bra.b freLoop
freIndirect:	; Eintrag "indirekt", d. h. innerhalb anderem Eintrag, vorhanden?
	lea FreeStore__HashTable,a6
	moveq #HushAnz-1,d2
freSchleif:	; Hashtables durchackern:
	move.l a6,a0
	addq.l #4,a6
freInIt:	move.l (a0),d1
	beq.b freNextList
	cmp.l a1,d1
	bhi.b freInNot
	move.l a0,-(a7)
	move.l d1,a0
	add.l 4(a0),d1
	move.l (a7)+,a0
	cmp.l a1,d1
	bhs.b freThats
freInNot:	move.l (a0),d1
	move.l d1,a0
	bra.b freInIt
freNextList:
	dbra d2,freSchleif
	bra.b freFail
freThats:	move.l (a0),a1
freFound:
	move.l (a1),(a0)
	move.l 4(a1),d0
	move.l ExecBase.w,a6
	jsr FreeMem(a6)
freret:	movem.l (a7)+,d0-d2/a0/a1/a6
	rts
freFail:	move.l #996,d0
	move.l d0,-(a7)
	move.l d0,_errno
	jsr exit__i


_EXIT_1_Please_free_Allocated_Store:
	lea FreeStore__HashTable,a0
	moveq #HushAnz-1,d1
CleanUp:	move.l (a0),d0
	beq.b CleanNext
	addq.l #8,d0
	move.l d0,-(a7)
	bsr _free
	addq.l #4,a7
	bra.b CleanUp
CleanNext:	addq.l #4,a0
	dbra d1,CleanUp
	rts

___MEMFLAGS:	dc.l $10000

	section bss,"bss"

FreeStore__HashTable:	blk.l HushAnz,0

	end

