/
/lws001 2-jan-80 Correct allocation in case task is pr:4 or 5
/
/
/ Dynamic space manager.
/
 
	.globl	alloc
	.globl	free
	.globl	cfree
	.globl	malloc
	.globl	mfree
	.globl	freesp

	.globl	__aloc
	.globl	__free
	.globl	__mavl
	.globl	__mtop
	.globl	__mlim
 
SLOP	=	8.		/Fuzz
EXTK	=	89.+[3.<<8.]	/EXTK dic
GPRT	=	65.+[4.<<8.]	/GPRT dic

__mavl:	.word 0			/Free list head
	.word 0

__mtop:	.word 0			/Top of mem+1 (0 if not set)
__mlim:	.limit			/Limits

bcm:	.asciz	"Bad call to `__free' (%06o)"
	.even

/
/ User interface.
/ char *malloc(n);	/* If no space, NULL */
/ char  *alloc(n);	/* If no space, -1 */
/
/ mfree(p);
/  free(p);
/ cfree(p);
/
/ int freespace();
/

alloc:	mov	2(sp),r0	/ Grab size.
	call	__aloc		/ Try to allocate the space.
	tst	r0		/ Well ?
	bne	0f		/ Br if all ok.
	mov	$-1,r0		/ Convert NULL to -1
0:	return			/ Done.


malloc:	mov	2(sp),r0	/ Grab size.
	callr	__aloc		/ Try to allrocate the space.

free:
cfree:
mfree:	mov	2(sp),r0
	callr	__free
 
freesp:	clr	r0
	mov	__mavl,r1
	beq	1f
0:	add	2(r1),r0
	mov	(r1),r1
	bne	0b
1:	return

/
/ __aloc.
/ Internal allocate routine.
/ Input: r0=size (bytes).
/ Output: r0=ptr to space or NULL.
/

__aloc:	mov	r3,-(sp)	/Save registers
	mov	r2,-(sp)
 
	tst	__mtop		/First call ?
	bne	1f		/Br if not

	mov	r0,r3		/Save size
	sub	$6,sp		/Get a GPRT buffer
	mov	sp,r1		/Do it
	mov	r1,-(sp)	/Big cheer for the PDP-11 !!
	clr	-(sp)
	clr	-(sp)
	mov	$GPRT,-(sp)
	emt	377
	bcc	0f		/Ok
	add	$6,sp		/Say no space
	br	2f

0:	mov	2(sp),r1	/Size (clicks)
	asl	r1		/Convert to bytes
	asl	r1
	asl	r1
	asl	r1
	asl	r1
	asl	r1
	add	_dsw,r1		/Top of memory (Correctly!)
/+ lws001
/
/Check stack size to determine if task is pr:4 or 5
/
	mov	__mlim, r0	/Lowest possible value for stack
	bic	$17777,r0	/Get rid of values <16k wds
	add	r0,r1		/If r0 not 0, task is probably priv.
/- lws001
	mov	r1,__mtop
	add	$6,sp		/Discard buffer
	mov	__mlim+2,r0	/Base of core hole
	sub	r0,r1		/Get its size
	cmp	r1,$4		/Big enough to save ?
	blo	0f		/No
	mov	r0,(r0)		/mov r0,(r0)+ screws up
	tst	(r0)+		/on some cpu's.
	mov	r1,(r0)+
	call	__free

0:	mov	r3,r0		/Get size back

1:	add	$4+1,r0		/2 words + round
	bic	$1,r0
	cmp	r0,$6		/Check for bad call
	blo	2f		/Abort if allocating zero words

1:	mov	r0,r1		/Save rounded size
	mov	$__mavl,r3	/Point at free list

0:	mov	(r3),r2		/mov LINK(r3),r2
	beq	4f		/No space on the free list
	cmp	2(r2),r0	/Is it usable
	bhis	0f
	mov	r2,r3		/No, continue the search
	br	0b
 
0:	neg	r0		/Compute leftover
	add	2(r2),r0
	cmp	r0,$SLOP	/Use it all
	bhis	0f		/No
	mov	(r2),(r3)	/Yes, unlink the block
	mov	r2,r0		/Setup for return
	mov	r0,(r0)		/Check word
	tst	(r0)+		/
	mov	2(r2),(r0)+
	br	3f
 
0:	mov	r0,2(r2)	/Adjust size in the block
	add	r2,r0		/Get pointer to the space to return
	mov	r0,(r0)		/Check word
	tst	(r0)+		/
	mov	r1,(r0)+	/Put size in it
	br	3f		/Return
 
/
/ Out of space.
/ Try to grow.
/
 
4:	mov	r0,r3		/Save size
	add	$377,r0		/Get grow increment
	clrb	r0
	mov	r0,r2		/Save it, then
	ror	r0		/Convert to clicks (c clear!)
	ror	r0
	ror	r0
	ror	r0
	ror	r0
	ror	r0
	clr	-(sp)		/EXTK$S r0
	mov	r0,-(sp)
	mov	$EXTK,-(sp)
	emt	377
	bcs	2f		/No core !
	mov	__mtop,r0	/Get base of new mem.
	add	r2,__mtop	/Adjust top.
	mov	r0,(r0)		/Free new core.
	tst	(r0)+		/
	mov	r2,(r0)+
	call	__free
	mov	r3,r0		/Get size back and
	br	1b		/Try again
 
2:	clr	r0		/Return NULL
 
3:	mov	(sp)+,r2	/Return
	mov	(sp)+,r3
	return
 
/
/ __free.
/ Internal free routine.
/ Input: r0=ptr to block.
/ If the block is not a valid alloc
/ block it exits with the message
/ "Bad call to `__free' (nnnnnn).
/

__free:	mov	r4,-(sp)	/Save some registers
	mov	r3,-(sp)
	mov	r2,-(sp)
	mov	r1,-(sp)
 
	mov	-(r0),r1	/Get size
	cmp	-(r0),r0	/Valid ?
	beq	0f		/Probably
	cmp	(r0)+,(r0)+	/Put caller's arg. back
	mov	r0,-(sp)	/Print message
	mov	$bcm,-(sp)
	call	frerror
	iot			/Hmmmmm ...

0:	mov	$__mavl,r3	/Free list pointer

0:	mov	(r3),r2		/Walk down the list until
	beq	1f		/The end
	cmp	r2,r0		/Or the correct place is found
	bhi	0f
	mov	r2,r3
	br	0b
 
0:	mov	r0,r4		/Test for collapse top end
	add	r1,r4
	cmp	r4,r2		/If they hit
	bne	1f
	add	2(r2),r1	/Join them together
	mov	(r2),(r0)
	br	0f
 
1:	mov	r2,(r0)		/Otherwise just link it in
 
0:	mov	r3,r4		/Test for collapse bottom end
	add	2(r3),r4
	cmp	r4,r0
	bne	1f
	add	r1,2(r3)	/Merge them
	mov	(r0),(r3)
	br	0f
 
1:	mov	r0,(r3)		/Otherwise finish linking it in
	mov	r1,2(r0)
 
0:	mov	(sp)+,r1	/Return
	mov	(sp)+,r2
	mov	(sp)+,r3
	mov	(sp)+,r4
	return
