
	.align	4
	.arm
	

@*************************************************:
@*:
@*: mem_init
@*:
@*: 	r0 	= base
@*: 	r2 	= len
@*:
@*************************************************@******:

	.global		mem_init
	.type		mem_init,function	
	

mem_init:

	stmfd	sp!,{r0,r1,r2,r3}

	mov	r1,#0	
	mov	r3,#8+(4*3)	@content size used,free&size + overhead
	
	str	r1,[r0]		@next (first element)
	str	r3,[r0,#4]	@size
	str	r1,[r0,#8]	@use counter
	str	r2,[r0,#12]	@free_size
	str	r2,[r0,#16]	@size
	
	ldmfd	sp!,{r0,r1,r2,r3}
	
	bx	lr

@*************************************************:
@*:
@*: mem_malloc
@*:
@*: 	r0 	= base
@*: 	r6 	= size
@* ret: r2 	= adr to free mem or 0
@*:	
@*:
@*************************************************:

	.global		mem_malloc
	.type		mem_malloc,function

mem_malloc:		

	stmfd	sp!,{r1,r3-r9}

	ldr	r8,[r0,#16]	@base->size
	add	r8,r8,r0	@overflowadr=base+base->size

	ands	r5,r6,#0x3	@kein durch 4 teilbar?
	bicne	r6,r6,#0x3	@dann rest weg
	addne	r6,r6,#4	@und 4 plus
	
	add	r6,r6,#8	@noch 8 für overhead (next/size)
	
	mov	r7,r0		@svae base
	mov	r5,r0		@last = base
	
find_free:
		
	ldmia	r0,{r3,r4}	@next element@
				@size of this element
	
	@**** overflow test
	
	add	r9,r0,r6	@akt_element + gewünschter Size > Overlow 
	cmp	r9,r8		@dann return(0)@
	movhi	r2,#0
	ldmhifd	sp!,{r1,r3-r9}
	movhi	pc,lr	
	
	@**** last element
	
	cmp	r3,#0		@next 0, dann nehmen wir es
	beq	set_element_tail
	
	@**** leakcheck
	
	add	r1,r0,r4	@this + size of this element = this.lenght
	sub	r2,r3,r1	@next - this = leaksize
	cmp	r2,r6		@if leaksize >= will size
	bge	set_element_insert
		
	
		
	@**** gehe zum nächsten element	
		
	mov	r5,r0		@last = this
	mov	r0,r3		@this = next
	b	find_free


@*************************************************:
@*:
@*: set_element_insert
@*:
@*: 	r1 = this+size = me
@*: 	r3 = next
@* ret: r2 	= adr to free mem or 0
@*:	
@*:
@*************************************************:

	.global		set_element_insert
	.type		set_element_insert,function

set_element_insert:	
		
	str	r1,[r0]		@this->next = me@
	stmia	r1,{r3,r6}	@me->next   = this->next@	
				@me->length = length
	
	add	r2,r1,#8	@return me+8
	ldmfd	sp!,{r1,r3-r9}
	mov	pc,lr

@*************************************************:
@*:
@*: set_element_tail
@*:
@*: 	r0 = dest
@*: 	r5 = next
@* ret: r2 	= adr to free mem or 0
@*:	
@*:
@*************************************************:

	
	.global		set_element_tail
	.type		set_element_tail,function

set_element_tail:

	
	mov	r1,#0
	
	add	r2,r0,r4	@next = this + this->size 	
	str	r2,[r0]		@this->next = me
	
	stmia	r2,{r1,r6}	@me->next   = 0
				@me->lenght = length
		
	add	r2,r2,#8	@return me+8
	ldmfd	sp!,{r1,r3-r9}
	mov	pc,lr
	
@*************************************************:
@*:
@*: mem_free
@*:
@*: 	r0 = base
@*: 	r6 = memadr
@*:
@*************************************************:	

	.global		mem_free
	.type		mem_free,function

mem_free:

	stmfd	sp!,{r0-r9}

	mov	r5,r0		@last = base
	sub	r6,r6,#8	@skip overhead
	
	mov	r7,r0

scan_memlist:

	ldmia	r0,{r3,r4}	@next element,size
	
	cmp	r3,r6		@remove this mem
	beq	mem_rem
	
	cmp	r3,#0		@?? out of list
	beq	free_not_found
	
	mov	r0,r3
	mov	r5,r3
	b	scan_memlist

free_not_found:

	@**** mache fehler meldung

	ldmfd	sp!,{r0-r9}
	mov	pc,lr

mem_rem:

	ldr	r0,[r6]		@r0 = this->next
	
	mov	r1,#0
	str	r1,[r6]		@this->next 	= 0 (nicht unbedingt nötig, nur für besseres debugging)
	str	r1,[r6,#4]	@this->length 	= 0
	
	str	r0,[r5]		@last->next = r0

	ldmfd	sp!,{r0-r9}
	mov	pc,lr	
	
@*************************************************:
@*:
@*: mem_trace
@*:
@*: 	  r0 = base
@-:
@*: return r1 = alloc cnt
@*:	  r2 = free_size
@*:	  r3 = leek cnt  
@*:	  r4 = leek size
@*:	  r5 = absolute used
@*:	
@*:
@*************************************************:

	.global		mem_trace
	.type		mem_trace,function

mem_trace:

	mov	r1,#0		@alloc_cnt = 0
	mov	r3,#0		@leek_cnt = 0
	mov	r4,#0		@leek_size = 0
	mov	r5,#0		@absolute_used = 0
	
	mov	r8,r0		@last=base
	mov	r9,r0		@savebase=base

scan_ml:
	
	ldmia	r0,{r6,r7}	@next element@
				@size of this element
						
	add	r10,r0,r7	@this + size of this element = this.lenght
	sub	r11,r10,r6	@next - this = leaksize			
			
			
	add	r1,r1,#1	@alloc_cnt ++@	
	cmp	r11,#0
	addne	r3,r3,#1	@leekcnt++ (wenn leak>0)		
	addne	r4,r4,r10	@leeksize+=leak
	
	sub	r10,r10,r9	@
	add	r5,r5,r10	@abolute_used+=this.length-base
			
	cmp	r6,#0
	beq	scan_ml_halt				
			
	mov	r8,r6		@last = this
	mov	r0,r6		@this = next			
	b	scan_ml				

scan_ml_halt:

	ldr	r2,[r9,#16]	@base->size
	sub	r2,r2,r5	@size-=absolute used

	sub	r4,r4,r9
	sub	r4,r4,#0x14
	sub	r3,r3,#1
	
		

	mov	pc,lr


@*************************************************:
@*********: 	stack 		   ***************
@*************************************************:



@*************************************************:
@*:
@*: stack_alloc
@*:
@*: 	  r0 = size
@*:
@*: return r1 = space addr
@*:
@*************************************************:

	.global		stack_alloc
	.type		stack_alloc,function

stack_alloc:
	
	tst	r0,#3		@aufrunden auf 4
	bicne	r0,r0,#3
	addne	r0,r0,#4
				
	mov	r1,sp		@jetzige pos
	sub	sp,sp,r0	@sp-size
	stmfd	sp!,{r1}	@-sp=backadr
	add	r1,sp,#4	@sp+4 = userspace -> back to user
	
	bx	lr
	
@*************************************************:
@*:
@*: stack_free
@*:
@*************************************************:

	.global		stack_free
	.type		stack_free,function

stack_free:
	
	ldr	sp,[sp]	
	bx	lr
	
	
@*************************************************:
@*********: 	stack THMUB        ***************
@*************************************************:

	.thumb
	.align	4

@*************************************************:
@*:
@*: stack_alloc_th
@*:
@*: 	  r0 = size
@*:
@*: return r1 = space addr
@*:
@*************************************************:

stack_alloc_th:
	
	mov	r1,#3
	tst	r0,r1		@aufrunden auf 4
	beq	stack_no_ra
	bic	r0,r1
	add	r0,r0,#4	@aufrunden
	
stack_no_ra:	

	mov	r2,sp		@jetzige pos
	sub	r1,r2,r0	@r1=sp-size	(r1=spaceadr)
	mov	sp,r1		@sp=r1
	push	{r2}		@-sp=backadr
	
	bx	lr
	
@*************************************************:
@*:
@*: stack_free_th
@*:
@*************************************************:

stack_free_th:
	
	ldr	r0,[sp]
	mov	sp,r0
	bx	lr
	
	.end
	