; int	_DivUnsArrByPwrOf10(a, n, p)
 ;
 ; ARGUMENT
 ;	unsigned	a[]	n-word number to divide
 ;	int		n	number of digits
 ;	int		p	power of 10 to divide by
 ;
 ; DESCRIPTION
 ;	Divides	a n-word 'a' by	a power	of 10, c = a / 10^p,
 ;  a>=0, p>0, rounding	the result.  c is correct only if a / 10^p < 2^79.
 ;
 ; SIDE	EFFECTS
 ;	The value of a is destroyed (it	isn't needed later).
 ;
 ; RETURNS
 ;	None.  (always succeeds)
 ;
 ; AUTHOR
 ;  Jared Levy	7/9/89
 ;   Copyright (C) 1989-90 Greenleaf Software Inc.  All	Rights Reserved.
 ;
 ; MODIFICATIONS
 ;
 ;
 ;
	include	model.h
	include	prologue.h
	include	gm.equ

	dseg	dmbyp10
p10	dw	1d,10d,100d,1000d,10000d
	endds

	pseg	dmbyp10
	cproc	_DivUnsArrByPwrOf10,,_dmbyp10

; load parameters

if	_LDATA
	mov	ax, parm4_	; get power of 10 to divide by
else
	mov	ax, parm3_	; get power of 10 to divide by
endif

	cmp	ax, 0		; if dividing by 10^0=1,
	je	qexit		;  nothing need	be done

if	_LDATA
	push	es
	les	di, parm1_	; get pointer to source	& destination
	mov	bx, parm3_	; get number of	digits
else
	mov	di, parm1_	; get pointer to source	& destination
	mov	dx, ds
	mov	es, dx
	mov	bx, parm2_	; get number of	digits
endif

	cmp	ax, 4		; Is the division by less than 10^4?
	jle	less4d

d10000:
	mov	cx, 10000d	; divide by 10000=10^4
d4loop:
	push	ax		; save ax & bx
	push	bx
	call	near ptr dmby1a3		; division
	pop	bx		; restore ax & bx
	pop	ax
	sub	ax, 4		; 4 less powers	of 10 to divide	by
	cmp	ax, 4		; are there 4 more left	to do?
	jg	d4loop		; yes, do it again

less4d:
	mov	si, ax
	sal	si, 1
	mov	cx, p10[si]	; load correct power of	ten
	call	near ptr dmby1ra3		; division, with rounding

if	_LDATA
	pop	es
endif
qexit:
	cproce

dmby1a3:
	dec	bx		; digits go from 0 to n-1
	sal	bx, 1		; want bytes rather than words

;/* skip initial zeroes	*/
;	for(;(q>0)&&(c[q-1]==0);q--);
;
;	if (q == 0)
;		return(0);
;	q--;			/* q will be used for subscript	*/
zeroloop:
	mov	ax, word ptr es:[di+bx]	; get digit
	cmp	ax, 0			; is digit zero?
	jne	nonzero			; if non-zero, begin divide
	dec	bx			; next word
	dec	bx
	cmp	bx, 0			; last digit?
	jge	zeroloop		; if not, process next digit
	xor	ax, ax			; otherwise, remainder 0
	jmp	short exit1		;  && division through (0/c=0)

;	bl = (unsigned long) b;
;	while (q>=0)  {
;		k = (unsigned long *) &r[q];
;		cl = *k	/ bl;
;		c[q] = (unsigned) cl;
;		r[q] = (unsigned) (*k -	cl * bl);
;		q--;
;		}
nonzero:
	xor	dx,dx			; high word zero in first divide
divloop:
	div	cx			; divide digit
	mov	word ptr es:[di+bx], ax	; store	quotient digit
	cmp	bx, 0			; last digit?
	je	exit2			; if so, division complete
	dec	bx			; next digit
	dec	bx
	mov	ax, word ptr es:[di+bx]	; get digit
	jmp	short divloop		; process digit

exit2:
	mov	ax, dx			; return remainder
exit1:
	ret

dmby1ra3:
	dec	bx		; digits go from 0 to n-1
	sal	bx, 1		; want bytes rather than words

;/* skip initial zeroes	*/
;	for(;(q>0)&&(c[q-1]==0);q--);
;
;	if (q == 0)
;		return(0);
;	q--;			/* q will be used for subscript	*/
rzeroloop:
	mov	ax, word ptr es:[di+bx]	; get digit
	cmp	ax, 0			; is digit zero?
	jne	rnonzero			; if non-zero, begin divide
	dec	bx			; next word
	dec	bx
	cmp	bx, 0			; last digit?
	jge	rzeroloop		; if not, process next digit
;	xor	ax, ax			; otherwise, remainder 0
	jmp	short rexit1		;  && division through (0/c=0)

;	bl = (unsigned long) b;
;	while (q>=0)  {
;		k = (unsigned long *) &r[q];
;		cl = *k	/ bl;
;		c[q] = (unsigned) cl;
;		r[q] = (unsigned) (*k -	cl * bl);
;		q--;
;		}
rnonzero:
	xor	dx,dx			; high word zero in first divide
rdivloop:
	div	cx			; divide digit
	mov	word ptr es:[di+bx], ax	; store	quotient digit
	cmp	bx, 0			; last digit?
	je	rexit2			; if so, division complete
	dec	bx			; next digit
	dec	bx
	mov	ax, word ptr es:[di+bx]	; get digit
	jmp	short rdivloop		; process digit

; round	up if remainder	> (divisor-1)/2
rexit2:
	dec	cx			; set cx = (cx-1)/2
	sar	cx, 1
	cmp	dx, cx			; test for rounding up
	ja	inclp			; if remainder is large, round up
	ret
inclp:
	inc	word ptr es:[di]
	jnz	rexit1
	inc	di
	inc	di
	jmp	short inclp

rexit1:
	ret
	endps
	end