	.asciz "$Header: asmstuff.s,v 820.1 86/12/04 19:52:44 root Exp $"
	.asciz "%W% %Y% %Q% %G%"
	.even

|------------------------------------------------------------------------
|
|				Copyright  1984
|
|			VALID  LOGIC  SYSTEMS  INCORPORATED
|
|	This listing contains confidential proprietary information which
|	is not to be disclosed to unauthorized persons without written
|	consent of an officer of Valid Logic Systems Incorporated.
|
|	The copyright notice appearing above is included to provide
|	statutory protection in the event of unauthorized or
|	unintentional public disclosure.
|
|------------------------------------------------------------------------

|
| Remove an entry from a doubly linked queue.
| The first long word is the forward pointer
| and the second is the backward pointer.  Return
| the address of the entry unlinked.
|
	.globl	remque, _remque

_remque:
remque:
	movl	sp@(4),a0	| pointer to the entry
	movl	a0@,a1		| pointer to forward entry
	movl	a0@(4),a1@(4)	| backward pointer
	movl	a0@(4),a1	| pointer to backward entry
	movl	a0@,a1@		| forward pointer
	movl	a0,d0
	rts
|
| Insert the second argument into the doubly
| linked queue immediately after the first
| argument
| 
	.globl	insque, _insque

_insque:
insque:
	movl	sp@(4),a0	| entry
	movl	sp@(8),a1	| pred
	movl	a1@,d0		| (pred)
	movl	d0,a0@		| (entry) <- (pred)
	movl	a1,a0@(4)	| (entry+4) <- pred
	exg	a0,d0		| d0 = entry, a0 = (pred)
	movl	d0,a0@(4)	| ((pred)+4) <- entry
	movl	d0,a1@		| (pred) <- entry
	rts
|
| bclear(ptr,n)
| register char *ptr;
| register int n;
| {
|	while (--n>=0) *ptr++=0;
| }
	.globl bclear,bzero, blkclr
bclear:
bzero:
blkclr:
	moveml sp@,#0x0301	|d0=retaddr  a0=ptr  a1=n
	movl a1,d0		|d0=n
	movl a0,d1		|d1=ptr
	btst #0,d1
	jne bzsrcodd
bz1:
	asrl #1,d0
	jle bzsmall
	jcs bzendodd
bz00:
	asrl #1,d0
	jcc bzmovl
	clrw a0@+		|n===2 (mod 4)
	jra bzmovl
bzlgo:	clrl a0@+
bzmovl:	dbra d0,bzlgo
	swap d0
	dbra d0,bzbigl
	rts
bzbigl:
	swap d0
	jra bzlgo

bzendodd:
	bsrs bz00
bzbyte:
	clrb a0@+
	rts

bzsmall:
	jcs bzbyte
bzrts:	rts

bzsrcodd:
	subql #1,d0
	jlt bzrts
	clrb a0@+
	jra bz1
	
|
| bcopy(src,dst,n)
| register char *src,*dst;
| register int n;
| {
|	while (--n>=0) *dst++= *src++;
| }
|
	.globl bcopy,blt
blt:
	moveml sp@,#0x0303	|d0=retaddr  d1=dst  a0=src  a1=n
	exg d1,a0		|            d1=src  a0=dst
	jra blt00
bcopy:
	moveml sp@,#0x0303	|d0=retaddr  d1=src  a0=dst  a1=n
blt00:
	btst #0,d1
	exg d1,a0		|cc same     d1=dst  a0=src
	jne bcsrcodd
	btst #0,d1
	exg d1,a1		|            d1=n            a1=dst
	jne bcmovb
bcopy1:
	asrl #1,d1		|test length and parity
	jle bcsmall
	jcs bcendodd
bc000:		| src, dst, n are all even; n is positive
	asrl #1,d1
	jcc bcmovl
	movw a0@+,a1@+		|n===2 (mod 4)
	jra bcmovl
bclgo:	movl a0@+,a1@+
bcmovl:	dbra d1,bclgo
	swap d1
	dbra d1,bcbigl
	rts
bcbigl:		|more than 64K 'movl'
	swap d1
	jra bclgo

bcendodd:	|src and dst even, n odd
	bsrs bc000
bcbyte:		|one byte
	movb a0@+,a1@+
	rts

bcsmall:	|0 or 1 byte
	jcs bcbyte
	rts

bcbgo:	movb a0@+,a1@+		|src ^ dst odd
bcmovb:	dbra d1,bcbgo
	swap d1
	dbra d1,bcbigb
bcrts:
	rts

bcbigb:		|more than 64K 'movb'
	swap d1
	jra bcbgo

bcsrcodd:	|src odd
	btst #0,d1
	exg d1,a1		|           d1=n            a1=dst
	jeq bcmovb
	subql #1,d1
	jlt bcrts
	movb a0@+,a1@+		|align to bus boundary
	jra bcopy1
|
| Copy bytes from one location to another in reverse
| order in the case the destination overlaps the source.
|
|	ovbcopy(from, to, size)
|
	.globl	ovbcopy

ovbcopy:
	movl	sp@(4),a0	| source address
	movl	sp@(8),a1	| destination address
	cmpl	a0,a1
	jle	bcopy		| destination is greater than source

	movl	sp@(12),d0	| byte count
	addl	d0,a0		| point just beyond source
	addl	d0,a1		| point just beyond destination
	jra	2$
1$:
	movb	a0@-,a1@-	| copy each byte
2$:
	dbf	d0,1$
	rts

oldbcopy:
	movl	sp@(4),a0	| source address
	movl	sp@(8),a1	| destination address
	movl	sp@(12),d0	| size
	jeq	justrts		| nothing to copy, just return
	movl	a0,d1
	orl	sp@(8),d1
	andl	#1,d1		| is one of the addresses odd?
	jeq	fastcopy	| no, we can fast copy
	movl	a0,d1
	andl	sp@(8),d1
	andl	#1,d1		| are both of the addresses odd?
	jne	copy1st		| yes, do first by hand then fast copy
	subql	#1,d0
slowloop:
	movb	a0@+,a1@+	| do the copy a byte at a time
	dbf	d0,slowloop
	rts
copy1st:
	movb	a0@+,a1@+	| copy first byte so addresses a even
	subql	#1,d0
fastcopy:
	bclr	#0,d0		| copying an odd number of bytes?
	jeq	1$
	movb	a0@(0,d0:l),a1@(0,d0:l) | yes, copy the very last byte
1$:
	bclr	#1,d0		| now are we copying an odd number of words?
	jeq	2$
	movw	a0@(0,d0:l),a1@(0,d0:l) | yes, copy the very last 16 bit word
2$:
	lsrl	#2,d0		| get count of longwords
	jeq	justrts		| just return if there is nothing more to copy
	subql	#1,d0
3$:
	movl	a0@+,a1@+	| copy each long word
	dbf	d0,3$
justrts:
	rts
|
| Declarations needed to make the kernel
| load.  These should come from the C library
| or should be massaged using a sed script
| to be in-line code instead of calls.
|

	.globl	spl0, spl1, spl2, spl3, spl4, spl5, spl6, spl7, splx
	.globl	splimp, splnet, rpl

rpl:	movw	sr,d0
	rts

spl7:
	movw	sr,d0
	movw	#0x2700,sr
	rts
spl6:
	movw	sr,d0
	movw	#0x2600,sr
	rts
splimp:
splnet:
spl5:
	movw	sr,d0
	movw	#0x2500,sr
	rts
spl4:
	movw	sr,d0
	movw	#0x2400,sr
	rts
spl3:
	movw	sr,d0
	movw	#0x2300,sr
	rts
spl2:
	movw	sr,d0
	movw	#0x2200,sr
	rts
spl1:
	movw	sr,d0
	movw	#0x2100,sr
	rts
spl0:
	movw	sr,d0
	movw	#0x2000,sr
	rts
splx:
	movl	sp@(4),d0
	movw	d0,sr
	rts
|
| char *
| stkalloc(nbytes)
| int nbytes;
| {
|	/* allocate variable-sized dynamic local storage.
|	/* MUST NOT BE CALLED FROM WITHIN AN ENCLOSING CALL.
|	/*    foo( ..., stkalloc(n), ...);   IS ILLEGAL.
|	*/
| }
	.globl stkalloc,stkfree
stkalloc:
	movl sp@+,a0		|return address
	movl sp@+,d0		|nbytes
	addql #1,d0		|round up
	bclr #0,d0		|  to even
	subl d0,sp		|allocate space
	movl sp,d0		|return value
	subql #4,sp		|compensate for caller's parameter removal
	jmp a0@
stkfree:
	movl sp@+,a0		|return address
	movl sp@+,d0		|nbytes
	addql #1,d0		|round up
	bclr #0,d0		|  to even
	addl d0,sp		|reclaim space
	movl sp,d0		|return value
	subql #4,sp		|compensate for caller's parameter removal
	jmp a0@
