; BlockEq.mu -- Fast Block compare instruction
; Copyright Xerox Corporation 1979
; Last modified September 10, 1979  6:04 PM by Boggs

; Accepts in:
;	AC0/	address of block0
;	AC1/	address of block1
;	AC3/	number of words to compare

; Returns:
;	AC3/	offset of first not equal pair of words

$AC0	$R3;	The accumulators
$AC1	$R2;
$AC2	$R1;
$AC3	$R0;
$PC	$R6;	Program counter
$NWW	$R4;	New wakeups waiting

!1,2,BeMore,BeDone;
!1,2,BeMaybeInt,BeNoInt;
!1,2,BeError,BeMain;
!1,2,BeDoInt,BeIntOff;

BlockEq: L← AC1-1;
	AC1← L;
	MAR← L← AC0, :Be2;

; main loop is 12 cycles - runs memory at full (single word) speed

BeMain:	MAR← L ← AC0+1;		Fetch a word from block 0
Be2:	AC0← L;
	L← AC3-1, BUS=0;	Update count, check for done
	AC3← L, :BeMore;	[BeMore,BeDone]
BeMore:	T← MD;
	MAR← L← AC1+1;		Fetch a word from block 1
	AC1← L;
	L← NWW, BUS=0;		Check for interrupts
	SH<0, :BeMaybeInt;	[BeMaybeInt,BeNoInt]
BeNoInt: L← MD-T;		Check for words equal
BeIntOff: SH=0, TASK;
	:BeError;		[BeError,BeMain]

BeMaybeInt: L← MD-T, :BeDoInt;	[BeDoInt,BeIntOff]
BeDoInt: L← PC-1, TASK;		Save state for interrupt
	PC← L;
BeError: SWMODE, L← AC3+1, :Be3; Come here on compare error
BeDone:	SWMODE, L← AC3+1;	Come here when done
Be3:	AC3← L, :START;