154 lines
3.8 KiB
NASM
154 lines
3.8 KiB
NASM
|
; void _MulUnsArr(src1,dst,num,n)
|
||
|
;
|
||
|
; ARGUMENT
|
||
|
; unsigned *src1[],*dst,num;
|
||
|
; int n;
|
||
|
;
|
||
|
; DESCRIPTION
|
||
|
; Multiplies the number src1(taken as one number of 'n' 16-bit int's)
|
||
|
; by 'num' and puts the result in dst. Note that it is assumed that
|
||
|
; the caller has made sure there are enough int's to hold the result.
|
||
|
; WE DON'T CHECK FOR OVERFLOW.
|
||
|
;
|
||
|
; SIDE EFFECTS
|
||
|
; None. Can't have more that 10 ints to multiply.
|
||
|
;
|
||
|
; RETURNS
|
||
|
; None.
|
||
|
;
|
||
|
; AUTHOR
|
||
|
; Andy Anderson 31-JAN-1987 15:10
|
||
|
; Copyright (C) 1987-90 Greenleaf Software Inc. All Rights Reserved.
|
||
|
;
|
||
|
; MODIFICATIONS
|
||
|
; aa 09-JUL-87 80-bit
|
||
|
;
|
||
|
|
||
|
include model.h
|
||
|
include prologue.h
|
||
|
include gm.equ
|
||
|
|
||
|
|
||
|
ReferVar wrgGMPartProd,<cWord>
|
||
|
|
||
|
dseg _gm
|
||
|
endds
|
||
|
|
||
|
pseg gmath
|
||
|
;
|
||
|
;
|
||
|
; if large memory model then:
|
||
|
;
|
||
|
; parm1_ = ptr to source 1 (segment and offset)
|
||
|
; parm3_ = ptr to destination (segment and offset)
|
||
|
; parm5_ = 16-bit multiplier
|
||
|
; parm6_ = number of ints in src1 (multiplicand)
|
||
|
;
|
||
|
; for if small model then
|
||
|
; parm1_ = ptr to source1
|
||
|
; parm2_ = ptr to destination
|
||
|
; parm3_ = 16-bit multiplier
|
||
|
; parm4_ = number of ints in src1 (multiplicand)
|
||
|
;
|
||
|
;
|
||
|
|
||
|
cproc _MulUnsArr,,_mli
|
||
|
|
||
|
if _LDATA
|
||
|
push es
|
||
|
les si,parm1_ ; ptr to src1
|
||
|
mov cx,parm6_ ; number of digits in multiplicand
|
||
|
else
|
||
|
mov si,parm1_ ; ditto for small model
|
||
|
mov cx,parm4_ ; number of digits in multiplicand
|
||
|
endif
|
||
|
ifdef DSNOTHING
|
||
|
mov ax,seg wrgGMPartProd
|
||
|
mov ds,ax
|
||
|
lea di,wrgGMPartProd
|
||
|
else
|
||
|
lea di,wrgGMPartProd ; ptr to partial prod array
|
||
|
endif
|
||
|
xor ax,ax ; clear flags
|
||
|
xor bx,bx ; clear offset
|
||
|
|
||
|
lp:
|
||
|
if _LDATA
|
||
|
mov ax,es:[bx+si] ; starting at lsd, get next highest
|
||
|
mul Word Ptr parm5_ ; result: dx(high) ax(low)
|
||
|
else
|
||
|
mov ax,[bx+si] ; starting at lsd, get next highest
|
||
|
mul Word Ptr parm3_ ; result: dx(high) ax(low)
|
||
|
endif
|
||
|
mov [bx+di],ax ; save partial products
|
||
|
mov [bx+di+2],dx
|
||
|
add di,2
|
||
|
add bx,2
|
||
|
loop lp
|
||
|
|
||
|
; Now that we're done with mult's, do the partial
|
||
|
; product adds and put them in dest.
|
||
|
;
|
||
|
ifdef DSNOTHING
|
||
|
mov ax,seg wrgGMPartProd
|
||
|
mov ds,ax
|
||
|
lea si,wrgGMPartProd
|
||
|
else
|
||
|
lea si,wrgGMPartProd ; ptr to partial prod array
|
||
|
endif
|
||
|
|
||
|
if _LDATA
|
||
|
les di,parm3_ ; ptr to destination
|
||
|
mov cx,parm6_ ; restore count for # of mult's
|
||
|
else
|
||
|
mov di,parm2_
|
||
|
mov cx,parm4_ ; restore count for # of mult's
|
||
|
endif
|
||
|
dec cx ; one less than the # of mult's
|
||
|
xor ax,ax
|
||
|
mov bx,0002h
|
||
|
|
||
|
;
|
||
|
; The first low-order partial product doesn't need to be
|
||
|
; added, just moved.
|
||
|
;
|
||
|
mov ax,[si] ; 1st 16-bit product just moves
|
||
|
if _LDATA
|
||
|
mov es:[di],ax
|
||
|
else
|
||
|
mov [di],ax
|
||
|
endif
|
||
|
cmp cx,0000h
|
||
|
je lastdig ; if we did only one mult
|
||
|
movlp:
|
||
|
mov ax,0000h
|
||
|
adc ax,[bx+si]
|
||
|
adc ax,[bx+si+2]
|
||
|
if _LDATA
|
||
|
mov es:[bx+di],ax
|
||
|
else
|
||
|
mov [bx+di],ax
|
||
|
endif
|
||
|
inc bx
|
||
|
inc bx
|
||
|
inc si
|
||
|
inc si
|
||
|
loop movlp
|
||
|
;
|
||
|
; Now just move in last digit from mult
|
||
|
lastdig:
|
||
|
mov ax,0000h
|
||
|
adc ax,[bx+si]
|
||
|
cmp bx,20 ; will throw away last word of
|
||
|
jge exit ; carry if more than 10 words max
|
||
|
if _LDATA
|
||
|
mov es:[bx+di],ax
|
||
|
exit: pop es
|
||
|
else
|
||
|
mov [bx+di],ax
|
||
|
exit:
|
||
|
endif
|
||
|
cproce
|
||
|
endps
|
||
|
END
|