; FtpUtilCompA.asm
; Copyright Xerox Corporation 1979
; Last modified February 11, 1978  11:24 PM by Boggs

.ent UBlockEq
.ent BlockEq

	.srel

UBlockEq:	.UBlockEq
BlockEq:	.BlockEq

	.nrel

; UBlockEq(adr1,adr2,count) - Microcode version
; Compare the count words starting at adr1 with the corresponding
; words starting at adr2, and return true iff all the corresponding
; words are equal.

.UBlockEq:
	sta 3 1 2
	lda 3 3 2		; get count
	#63400			; call microcode
	mov 3 3 szr		; ac3 = 0 if all is well
	sub 0 0 skp
	 adc 0 0
	lda 3 1 2
	jmp 1 3

; BlockEq(adr1,adr2,count) - Assembly language version
; Compare the count words starting at adr1 with the corresponding
; words starting at adr2, and return true iff all the corresponding
; words are equal.

.BlockEq:
	sta 3 1 2
	sta 0 2 2		; Store adr1
	mov 1 3			; ac3 ← adr2

; Compare the first (count mod 8) words one at a time
bleq1:	lda 0 3 2		; See if count mod 8 = 0
	lda 1 c7
	and# 0 1 snr
	 jmp bleq2		; Yes, go to fast loop
	lda 0 @2 2		; No, do slow compare of one word
	lda 1 0 3
	se 0 1
	 jmp bleq5		; Not equal, return false
	isz 2 2			; Equal, increment addresses
	inc 3 3
	dsz 3 2			; Decrement and test count
	 jmp bleq1

; Set up for fast loop
bleq2:	lda 0 3 2		; Compute count/8
	movzr 0 0
	movzr 0 0
	movzr 0 0 snr
	 jmp bleq4		; Less than 8 words in block
	sta 0 3 2		; Store count/8
	lda 0 2 2		; Get current adr1

; Fast loop.  ac0/ adr1, ac3/ adr2, count in frame temp 3.
; The portion inside dir...eir is non-reentrant due to the use
; of save2.
bleq3:	dir			; Interlock non-reentrant portion
	sta 2 save2		; Save frame pointer
	mov 0 2			; ac2 ← adr1

	lda 0 0 2		; Compare 8 words, to bleq6 if fail
	lda 1 0 3
	se 0 1
	 jmp bleq6

	lda 0 1 2
	lda 1 1 3
	se 0 1
	 jmp bleq6

	lda 0 2 2
	lda 1 2 3
	se 0 1
	 jmp bleq6

	lda 0 3 2
	lda 1 3 3
	se 0 1
	 jmp bleq6

	lda 0 4 2
	lda 1 4 3
	se 0 1
	 jmp bleq6

	lda 0 5 2
	lda 1 5 3
	se 0 1
	 jmp bleq6

	lda 0 6 2
	lda 1 6 3
	se 0 1
	 jmp bleq6

	lda 0 7 2
	lda 1 7 3
	se 0 1
	 jmp bleq6

	lda 0 c10
	add 0 3			; Increment adr2 by 8
	add 2 0			; Increment adr1 by 8, move to ac0
	lda 2 save2		; Recover frame pointer
	eir			; Now reentrant
	dsz 3 2			; Decrement and test count
	 jmp bleq3		; More to do

bleq4:	mkminusone 0 0 skp	; Here to return true
bleq5:	 mkzero 0 0		; Here to return false
	lda 3 1 2
	jmp 1 3

bleq6:	lda 2 save2		; Here to return false when
	eir			;  inside fast loop
	jmp bleq5

c7:	7
c10:	10
save2:	0
	.end