; multibyte math routines


divide16_8:
	clr	bh		; clear bh for divide
; max 212 cycles including call + return.
divide:
	clr	cl		;clear remainder Low byte
	clr	ch		;clear remainder High byte
	ldi	counter,17	;init loop counter
	sec
	rjmp	d16u_1		;else
d16u_2:	rol	cl		;shift dividend into remainder
	rol	ch
	sub	cl,bl		;remainder = remainder - divisor
	sbc	ch,bh		;
	brcc	d16u_1		;if result negative
	add	cl,bl		;    restore remainder
	adc	ch,bh
d16u_1:	rol	al		;shift left dividend
	rol	ah
	dec	counter		;decrement counter
	brne	d16u_2		;if done
	com	ah
	com	al
	ret			;    return

divide32_16:
	clr	bul
	clr	buh
	; fall through to divide32 routine
; divides EAX by EBX.
; The result is left in EAX, remainder in ECX, divisor (EBX) unchanged
; this routine takes 664 cycles max (including call and return)
divide32:
	clr	cl		;clear remainder Low byte
	clr	ch
	clr	cul
	sub	cuh,cuh		;clear remainder High byte and carry
	ldi	counter,33	;init loop counter (32 bits plus carry = 33)

	; shift until we have a bit going into ECX
d32pre:	sec
	rol	al		;shift left dividend
	rol	ah
	rol	aul
	rol	auh
	dec	counter
	breq	d32done
	brcc	d32pre
d32L1:	rol	cl		;shift dividend into remainder
	rol	ch
	rol	cul
	rol	cuh
	sub	cl,bl		;remainder = remainder - divisor
	sbc	ch,bh
	sbc	cul,bul
	sbc	cuh,buh
	brcc	d32u_1		;if result negative
	add	cl,bl		;    restore remainder
	adc	ch,bh
	adc	cul,bul
	adc	cuh,buh
d32u_1:	rol	al		;shift left dividend
	rol	ah
	rol	aul
	rol	auh
	dec	counter		;decrement counter
	brne	d32L1		;go back if not done
d32done:
	com	al
	com	ah
	com	aul
	com	auh
	ret			;    return

