; ScavUtilA.asm -- asm utility routines
; Copyright Xerox Corporation 1981, 1982
; Last modified May 3, 1982  4:59 PM by Boggs

.ent MulDiv, DoubleUsc
.ent GetBit, SetBit

	.srel
MulDiv:		.MulDiv
DoubleUsc:	.DoubleUsc
GetBit:		.GetBit
SetBit:		.SetBit

	.nrel

; MulDiv(a, b, c)
; returns the unsigned value (a*b)/c

.MulDiv:sta 3 1,2
	mov 2 3
	mov 0 2
	mkzero 0 0
	mul
	lda 2 3,3
	div
	 nop
	mov 1 0
	mov 3 2
	lda 3 1,2
	jmp 1,3

; DoubleUsc(lvA, lvB, nWords; numargs na) = -1|0|1
; Returns:	-1 if A < B
;		 0 if A = B
;		 1 if A > B
; lvA and lvB are the addresses of the nWords-word operands
; nWords defaults to 2.

.DoubleUsc:
	sta 0 1,2		; lvA
	sta 1 2,2		; lvB
	lda 0 0,3		; number of args
	lda 1 c2
	sne 0 1
	 sta 1 3,2		; default nWords to 2
uscLp:	lda 0 @1,2		; A word
	lda 1 @2,2		; B word
	sleu 0 1
	 jmp gr			; A > B
	sub 1 0 szr
	 jmp ls			; A < B
	isz 1,2			; lvA
	isz 2,2			; lvB
	dsz 3,2			; decrement and test nWords
	 jmp uscLp
	jmp 1,3			; all words equal. return zero

gr:	mkone 0 0 skp
ls:	 mkminusone 0 0
	jmp 1,3

c2:	2

; GetBit(lvBitArray, bitNumber) = value
; Reads a bit from a bit array.  The base of the array is lvBitArray
; and the index is bitNumber.  Returns the result as a BCPL boolean;
; i.e., a one is returned as -1 (BCPL true).

.GetBit:
	sta 3 1,2
	mov 0 3			; lvBitArray
	movzr 1 0		; bitNumber
	movzr 0 0
	movzr 0 0
	movzr 0 0
	add 0 3			; lvBitArray + bitNumber/16
	lda 0 0,3		; word from array
	cycle 0			; left-cycle bitNumber rem 16
	movl# 0 0 snc		; test result now in sign
	 mkzero 0 0 skp		; false
	 mkminusone 0 0		; true
	lda 3 1,2
	jmp 1,3


; SetBit(lvBitArray, bitNumber, value)
; Writes a bit into a bit array.  The base of the array is lvBitArray
; and the index is bitNumber.  The bit written is zero if value is
; zero, one if value is nonzero.

.SetBit:
	sta 3 1,2
	movzr 1 3		; bitNumber
	movzr 3 3
	movzr 3 3
	movzr 3 3
	add 3 0			; lvBitArray + bitNumber/16
	sta 0 2,2
	neg 1 1			; negate bitNumber for right shift
	adczr 0 0		; 77777B
	cycle 0			; left-cycle bitNumber rem 16
	lda 1 @2,2		; word from array
	and 0 1			; turn off the bit
	lda 3 3,2		; get value
	mov# 3 3 szr
	 adc 0 1		; nonzero, turn on the bit
	sta 1 @2,2		; store back into array
	lda 3 1,2
	jmp 1,3

	.end