	.title	String routines for Ultrix emulation
	.ident	"1.0-002"

	.psect	strings,exe,rel,shr,pic,nowrt

;
;  bcopy(src, dest, length)
;
;  char *src;		     /* source string */
;  char *dest;               /* dest string  */
;  unsigned long int length; /* length in bytes */
;
;  This routine copies the specified number of bytes from the source string
;  to the destination string. If the specified length is longer thatn 
;  64kb, then it copies 64kb each time until it is done.
;  
.entry bcopy,^M<R2,R3,R4,R5,R6,R7>
	movl	#65535,r7	; counter 
	movl	12(ap),r6	; amount to copy 
next_block:
	cmpl	r6,r7		; are we done yet?
	bgtru	do_copy
	movl	r6,r7		; only need to move what's left
do_copy:
	movc3	r7,@4(ap),@8(ap); move it
	subl2	r7,r6		; adjust counter to the next block
	bleq	copy_done
	movl	r1,4(ap)
	movl	r3,8(ap)
	brw	next_block	; do it again
copy_done:
	ret


;++
;
; bcmp( source, dest, len )
; char *source, *dest;
; int len;
;
; copies (len) bytes from (source) to (dest) regardless of contents
;
;--

.entry	bcmp,^m<r2,r3,r4,r5>

	cmpc3 12(ap),@4(ap),@8(ap)	; that's all, folks...
	beql	10$
	movl	#-1,R0	;fail
	ret
10$:	movl	#0,R0	;SUCCESS
	ret

;++
;
; bzero( dest, len )
; char *dest;
; int len;
;
; writes (len) zero bytes into dest
;
;--

.entry	bzero,^m<r2,r3,r4,r5>

	movc5 #0,@4(ap),#0,8(ap),@4(ap)	; will pad with nuls
	ret

;++
;
; int ffs( i )
; int i;
;
; finds the first bit set in the argument and returns the index
; of that bit (starting at 1).
;
;--

.entry	ffs,0

	ffs #0,#32,4(ap),r0
	beql 10$			; branch if arg=0
	incl r0				; VAX counts bits from 0
	ret
10$:	movl #-1,r0			; no set bits, return -1
	ret

;++
;
; char *index( string, c )
; char *string, c;
;
; returns pointer to first occurrence of character c within string
; or zero if not found.
;
;--

.entry	index,0

	locc #0,#-1,@4(ap)		; find end of string first
	subl 4(ap),r1			; compute length of string
	locc 8(ap),r1,@4(ap)		; now find char
	bneq 10$
	clrl r1				; clear pointer if not found
10$:	movl r1,r0			; return the pointer
	ret

;++
;
; char *rindex( string, c )
; char *string, c;
;
; returns pointer to last occurrence of character c within string
; or zero if not found.
;
;--


.entry	rindex,^M<R2>

	locc #0,#-1,@4(ap)		; find end of string first
	subl3 4(ap),r1,r0		; compute length of string
	clrl r2				; assume no occurrence
	movl 4(ap),r1			; starting address
10$:	locc 8(ap),r0,(r1)		; search from left
	beql 20$			; none there, done
	movl r1,r2			; save this pointer
	incl r1				; start again one byte to the right
	decl r0				; update new length
	bgtr 10$			; and continue search

20$:	movl r2,r0			; return last pointer found
	ret

	.end
