; int _MulUnsArrByPwrOf10(pa,n,w); ; ; ; ARGUMENTS ; unsigned *pa[] points to pa[10], a w word number ; (both input and output) ; int n Number of power of ten multiplier 0..47 ; int w Number of words (digits) ; ; DESCRIPTION ; Multiplies the input in the pa[] array (a w word number) ; by 10^n where 0<=n<=47. ; ; The application is in divide routines for adjusting the result. ; ; SIDE EFFECTS ; The value in the source array is unchanged on overflow. ; ; RETURNS ; GM_OVERFLOW if there is an overflow, otherwise GM_SUCCESS. ; ; ; 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 mul10 power dw 1 dup(?) ; power of ten to do numnz dw 1 dup(?) ; number of nonzero digits totdig dw 1 dup(?) ; total number of digits tmpdig dw 1 dup(?) ; temp. copy of number of non-zero digits p10 dw 1,10d,100d,1000d,10000d ; powers of 10 endds pseg mul10 cproc _MulUnsArrByPwrOf10,,_mul10 if _LDATA push es les di,parm1_ ; get pointer to source/destination mov dx,parm3_ ; get power of 10 mov bx,parm4_ ; get number of words else mov di,parm1_ ; get pointer to source/destination mov ax,ds mov es,ax mov dx,parm2_ ; get power of 10 mov bx,parm3_ ; get number of words endif mov si, di ; copy array location (for future recall) mov totdig, bx ; store number of digits ; dec power ; Find highest nonzero digit ; (so time isn't wasted multiplying zeroes) sal bx, 1 ; want digits in words lpnz: dec bx ; decrease word by 1 (2 bytes) dec bx jns nxtlin jmp success ; negative bx => source is 0 => done nxtlin: mov ax,0 cmp ax,word ptr es:[di+bx] je lpnz ; shr bx,1 ; want number of words, not bytes inc bx ; number of digits one more than digit number mov numnz,bx ; store # of non-zero digits mov tmpdig,bx ; store again (for counter) ; multiplies by 10000 for all multiplications but last to run faster ; find correct number to mul by & decrease power (# of remaining muls) bigloop: cmp dx, 4 ; check if multiplying by power greater than 4 jge pg4 mov ax, 0 ; if so, no subsequent muls needed mov power, ax sal dx, 1 ; get power of 10 mov bx, dx mov bx, p10[bx] jmp short bmul pg4: sub dx, 4 ; subtract 4 from remaining powers of 10 mov power, dx mov bx, 10000d ; begin multiplication, handling first digit specially bmul: mov ax, word ptr es:[di] ; get first digit mul bx ; multiply digit mov word ptr es:[di], ax ; store lower digit dec tmpdig ; decrease digit counter clc jz onedig ; only one digit ; now multiply remaining digits loop1: mov cx, dx ; save high word inc di ; go to next digit inc di mov ax, word ptr es:[di] ; get next digit pushf ; save carry flag mul bx ; multiply digit popf ; retrieve carry flag adc ax, cx ; add previous high word mov word ptr es:[di], ax ; store lower digit dec tmpdig ; check if any more digs to mul jnz loop1 ; handle carry into additional digit (contained in dx) onedig: adc dx, 0 ; add carry flag jz nomore ; if dx=0, no more nonzero digits ; if additional digit, increment digit # & store digit mov ax, numnz ; get old # of digits cmp ax, totdig ; check for overflow jge overflow ; if equal, overflow occured inc numnz ; one more digit now inc di ; digit goes in next word inc di mov word ptr es:[di], dx ; store high digit nomore: mov dx, power ; check if through cmp dx, 0 jz success mov ax, numnz ; get # of digits mov tmpdig,ax ; copy # of non-zero digits mov di, si ; copy pointer jmp short bigloop overflow: mov ax,GM_OVERFLOW ; indicate error jmp short through success: mov ax,GM_SUCCESS through: if _LDATA pop es endif cproce endps end