;  int	_MulUnsArrByPwrOf10Limited(pa, n, dig);
;
;
; ARGUMENTS
;	unsigned *pa[]	points to pa[10], a 160	bit number
;			(both input and	output)
;	int n		Number of power	of ten multiplier 0..19
;	int dig		Number of digits to multiply
;
; DESCRIPTION
;	Multiplies the input in	the pa[] array (a 160-bit binary number)
;	by 10^n	where 0<=n<=19.
;	If multiplication overflows, multiplies	by largest power of 10
;  which doesn't overflow and returns that power of ten.
;	The application	is in addition when lining up decimal points.
;
; SIDE EFFECTS
;	None.  (always succeeds)
;
; RETURNS
;	Power of ten multiplied	by, always <= n.
;
;
; AUTHOR
;	Don Killen    14-Jun-1988  15:19:03
 ;   Copyright (C) 1988-90 Greenleaf Software Inc.  All	Rights Reserved.
;
	include	model.h
	include	prologue.h
	include	gm.equ

	dseg	mul10l
power	dw	1 dup(?)		; power	of ten to do
numdig	dw	1 dup(?)		; number of nonzero digits
work	dw	12 dup (?)	; intermediate result array
hiword	dw	1 dup(?)		; byte # of highest word
	endds

	pseg	mul10l
	cproc	_MulUnsArrByPwrOf10Limited,,_mul10l
	if	_LDATA
	 push	es
	 les	di,parm1_	; get pointer to source/destination
	 mov	ax,parm3_	; get power of 10
	 mov	bx,parm4_	; get number of	digits
	else
	 mov	di,parm1_	; get pointer to source/destination
	 mov	ax,ds
	 mov	es,ax
	 mov	ax,parm2_	; get power of 10
	 mov	bx,parm3_	; get number of	digits
	endif

	mov	numdig,bx	; store	the number of digits
	mov	power,ax	; store	power of 10
	shl	bx, 1		; bytes	rather than words
	mov	dx, bx
	dec	dx		; highest byte # is two	less than # of bytes
	dec	dx
	mov	hiword,	dx	; store	location of highest word

;
; Strategy is to multiply by shifting left all 160 bits.
;
; a)	Move (parm1) ->	work array
; b)	shift left work	array twice, multiplying by 4
; c)	Add  (parm1) <=	(parm1)+work, multiplying by 5
; d)	Shift (parm1) left once, multiplying by	10
; e)	Test for overflow (carry out of	MSW) each step (jmp to error)
; f)	If no error, decrement power & loop to (a) if nonzero.
; g)	When power has been decremented	to 0, you're done!
;

;
;  Top of main loop, repeat from here 'power' times.
;
lp0:				; top of major loop.
;
;	Transfer the source to the work	array.	Work from msd down to lsd
;
	if	_LDATA
	 les	di,parm1_
	else
	 mov	di,parm1_
	endif

	mov	ax, 3276d		; if high word >= 3276,
	mov	bx, hiword		;  can't multiply any more
	cmp	ax, word ptr es:[di+bx]
	jg	canmul			; can multiply

if _LDATA				; No more mul's	possible
	mov	ax, parm3_		; From total multiplications,
else
	mov	ax, parm2_
endif
	sub	ax, power		; Subtract remaining mul's
	jmp	short overflow		; to return number of mul's

canmul:
	mov	si,0			; move msd first
	mov	cx,numdig
lp2:	mov	ax,word	ptr es:[di]	; load source word
	mov	word ptr work[si],ax	; store	in 'work'
	inc	si
	inc	si
	inc	di
	inc	di
	loop	lp2			; til done.
;
;  Shift the work array	left two bits.
;
	mov	cx,numdig		; loop count
	mov	si,0			; index	into work array
	clc
lp4:	rcl	word ptr work[si],1	; rotate with carry
	inc	si
	inc	si
	loop	lp4			; complete 1st shift (x2)

	mov	cx,numdig
	mov	si,0
	clc
lp5:	rcl	word ptr work[si],1	; rotate with carry
	inc	si
	inc	si
	loop	lp5			; complete 2nd shift (x4)
;
;  So far, work=pa*4.
;
;  Add pa=pa+work, making pa=pa*5
;
	if	_LDATA
	 les	di,parm1_	; get pointer to source/destination
	else
	 mov	di,parm1_	; get pointer to source/destination
	endif

	mov	cx,numdig
	mov	si,0
	clc
lp6:	mov	ax,word	ptr work[si]
	adc	word ptr es:[di],ax
	inc	di
	inc	di
	inc	si
	inc	si
	loop	lp6		; Added	orig array to 4x:  (x5)
;
;
;  At this point, pa=pa*5.  Now	shift it left making pa=pa*10
;
	if	_LDATA
	 les	di,parm1_
	else
	 mov	di,parm1_
	endif
	mov	cx,numdig
	clc
lp7:	rcl	word ptr es:[di],1	; rotate left to shift with carry.
	inc	di
	inc	di
	loop	lp7		; Multiplied (x5) by 2 making (x10) in src

; Code deleted 1/15/90 MRN
;
;  If no overflow has occurred,	decrement power	counter	and loop
;  through entire x10 routine.
;

dpow:	dec	power
	jz	mcomplete
	jmp	lp0		; major	loop

mcomplete:
if _LDATA
	mov	ax, parm3_	; did all requested multiplications
else
	mov	ax, parm2_
endif

overflow:
	if	_LDATA
	 pop	es
	endif
	cproce

	endps
	end