ba237a9d91
Files correlati : Ricompilazione Demo : [ ] Commento : Aggiunti i sorgenti per Greenleaf Math Library (gfm.dll) git-svn-id: svn://10.65.10.50/trunk@10079 c028cbd2-c16b-5b4b-a496-9718f37d4682
323 lines
8.7 KiB
NASM
Executable File
323 lines
8.7 KiB
NASM
Executable File
; int _MulUnsArrP10AndAddInt(pa,c);
|
|
;
|
|
; ARGUMENT
|
|
; unsigned *pa points to a pa[5], or 80-bit number
|
|
; int c # to add after mult by 10
|
|
;
|
|
; DESCRIPTION
|
|
; multiplies the number (<=80-bits) in the int array by decimal 10
|
|
; and adds 'c' to it. Used in the divide routines for adjusting
|
|
; the result.
|
|
;
|
|
; SIDE EFFECTS
|
|
; The value in the source array is indeterminate on overflow.
|
|
;
|
|
; RETURNS
|
|
; Returns GM_OVERFLOW on overflow, otherwise GM_SUCCESS.
|
|
;
|
|
; AUTHOR
|
|
; Andy Anderson 27-JUL-87 80-bit
|
|
; Copyright (C) 1987-90 Greenleaf Software Inc. All Rights Reserved.
|
|
;
|
|
; MODIFICATIONS
|
|
;
|
|
;
|
|
.SFCOND
|
|
|
|
include model.h
|
|
include prologue.h
|
|
include gm.equ
|
|
|
|
ReferVar wGMTemp1,<cWord>
|
|
ReferVar wrgGMPartProd,<cWord>
|
|
|
|
dseg _gm
|
|
endds
|
|
|
|
pseg gmath
|
|
;
|
|
; if large memory model then:
|
|
;
|
|
; parm1_ = ptr to source 1
|
|
; parm3_ = number to add to a*10
|
|
;
|
|
; for if small model then
|
|
; parm1_ = ptr to source1
|
|
; parm2_ = number to add to result of a * 10
|
|
;
|
|
|
|
cproc _MulUnsArrP10AndAddInt,,_mul10ad
|
|
|
|
if _LDATA
|
|
push ds
|
|
push es
|
|
lds si,parm1_ ; ptr to dst (=src)
|
|
else
|
|
mov si,parm1_
|
|
endif
|
|
;
|
|
; to multiply by 10, we mult by 4 using 2 shifts, add the
|
|
; original number making 5 times the original, then multiply
|
|
; that by 2 giving a multiplication by 10. This is many times
|
|
; FASTER than the mul instruction!!!
|
|
;
|
|
|
|
mov ax,[si+8] ; get msd for possible overflow
|
|
cmp ax,3000h ; overflow if sign sets during the
|
|
jl nxt ; first shift set
|
|
jmp overf
|
|
nxt: cmp ax,0bffh ; if < this, no overflow possible
|
|
jl ct ; no possibility of overflow
|
|
jmp tstover ; further testing needed
|
|
ct: xor ax,ax ; start clear for test
|
|
mov bx,8 ; offset to last int
|
|
mov cx,5 ; max number of ints in 80-bit value
|
|
numints:
|
|
or ax,[bx+si] ; see if upper 80 bits are set
|
|
jnz gotdig ; and stop when first one seen
|
|
dec bx
|
|
dec bx
|
|
loop numints ; if we find all of them zero
|
|
if _LDATA
|
|
mov ax,parm3_
|
|
else
|
|
mov ax,parm2_
|
|
endif
|
|
mov [si],ax ; just put it in low-order word
|
|
jmp gexit
|
|
gotdig:
|
|
ifdef DSNOTHING
|
|
push ds
|
|
mov ax, seg wGMTemp1
|
|
mov ds,ax
|
|
mov wGMTemp1,cx ; save # of digits in source
|
|
pop ds
|
|
else
|
|
mov wGMTemp1,cx ; save # of digits in source
|
|
endif
|
|
;
|
|
; then shift the number of ints figured for each loop
|
|
;
|
|
ifdef DSNOTHING
|
|
mov ax, seg wrgGMPartProd
|
|
mov es,ax
|
|
endif
|
|
lea di,wrgGMPartProd ; ptr to work area
|
|
|
|
xor bx,bx
|
|
mov dx,bx
|
|
shlp:
|
|
mov ax,[bx+si] ; do 16-bits at a time
|
|
clc
|
|
rcl dx,1 ; dummy first time thru
|
|
rcl ax,1 ; multiply by 2
|
|
rcl dx,1 ; save carry in dh (d1-d0)
|
|
rcl ax,1 ; now original * 4
|
|
rcl dx,1 ; and dx has shifted out bits
|
|
ifdef DSNOTHING
|
|
mov es:[bx+di],ax ; store temp result
|
|
else
|
|
mov [bx+di],ax ; store temp result
|
|
endif
|
|
ror dx,1
|
|
ror dx,1
|
|
inc bx
|
|
inc bx
|
|
loop shlp
|
|
;
|
|
; if we have bits shifted out into dx left over, then
|
|
; we have gained 1 int. This is overflow if we were already
|
|
; doing 5 int's!
|
|
;
|
|
|
|
or dx,0000h ; was max size number, if dx!=0
|
|
jz addin ; no bits shifted into carry
|
|
ifdef DSNOTHING
|
|
push ds
|
|
mov ax,seg wGMTemp1
|
|
mov ds,ax
|
|
inc wGMTemp1 ; otherwise, one more int in number
|
|
pop ds
|
|
else
|
|
inc wGMTemp1 ; otherwise, one more int in number
|
|
endif
|
|
rol dx,1 ; bits to low-order of next msd
|
|
rol dx,1 ; in lifo order
|
|
ifdef DSNOTHING
|
|
mov es:[bx+di],dx
|
|
else
|
|
mov [bx+di],dx
|
|
endif
|
|
;
|
|
; Then add the original for sum of 5 X original
|
|
;
|
|
addin: xor bx,bx
|
|
mov dx,bx
|
|
ifdef DSNOTHING
|
|
push ds
|
|
mov ax, seg wGMTemp1
|
|
mov ds,ax
|
|
mov cx,wGMTemp1 ; k int's in new number
|
|
pop ds
|
|
else
|
|
mov cx,wGMTemp1 ; k int's in new number
|
|
endif
|
|
clc
|
|
|
|
if _LDATA
|
|
les di,parm1_
|
|
else
|
|
mov di,parm1_
|
|
endif
|
|
ifdef DSNOTHING
|
|
mov ds,ax ; scrap old DS, get global one
|
|
endif
|
|
lea si,wrgGMPartProd
|
|
|
|
addlp:
|
|
if _LDATA
|
|
mov ax,[bx+si] ; do 16-bits at a time
|
|
adc es:[bx+di],ax
|
|
else
|
|
mov ax,[bx+si] ; do 16-bits at a time
|
|
adc [bx+di],ax
|
|
endif
|
|
inc bx
|
|
inc bx
|
|
loop addlp
|
|
|
|
; stop as soon as we get an overflow
|
|
rcl dx,1 ; save possible overflow
|
|
or dx,0000h ; see if bits left over
|
|
jz finshft ; no possible overflow or increase
|
|
inc wGMTemp1
|
|
if _LDATA
|
|
add es:[bx+di],dx
|
|
else
|
|
add [bx+di],dx
|
|
endif
|
|
jno finshft ; if sign-bit or carry didn't set: continue
|
|
xor dx,dx
|
|
inc dx
|
|
if _LDATA
|
|
mov es:[bx+di+2],dx
|
|
else
|
|
mov [bx+di+2],dx
|
|
endif
|
|
inc wGMTemp1 ; increase number of digits in dst
|
|
|
|
finshft:
|
|
xor bx,bx
|
|
mov dx,bx
|
|
mov cx,wGMTemp1 ; number of int's to shift
|
|
|
|
if _LDATA
|
|
lds si,parm1_
|
|
else
|
|
mov si,parm1_
|
|
endif
|
|
shlp3:
|
|
rcl Word Ptr [bx+si],1 ; multiply by 2= times 10
|
|
inc bx
|
|
inc bx
|
|
loop shlp3
|
|
|
|
;
|
|
; high-order bit of int 10 can't be set either
|
|
;
|
|
rcl dx,1 ; save carry bit
|
|
or dx,0000h ; was max size number, if dx!=0
|
|
jz cout ; no bits shifted into carry
|
|
ifdef DSNOTHING
|
|
push ds
|
|
mov ax,seg wGMTemp1
|
|
mov ds,ax
|
|
inc wGMTemp1 ; otherwise, one more int in number
|
|
cmp wGMTemp1,5 ; if working with 5-int number
|
|
pop ds
|
|
else
|
|
inc wGMTemp1 ; otherwise, one more int in number
|
|
cmp wGMTemp1,5 ; if working with 5-int number
|
|
endif
|
|
jg overf ;overflow: too many digits
|
|
|
|
mov [bx+si],dx
|
|
|
|
;
|
|
; If no overflow, see if we have mult'd # times requested
|
|
;
|
|
cout:
|
|
test [si+8],8000h ; see if high-order word set sign
|
|
jnz overf
|
|
|
|
xor bx,bx ; clear flags
|
|
mov dx,bx
|
|
ifdef DSNOTHING
|
|
push ds ; save parm1's DS and switch
|
|
mov ax,seg wGMTemp1
|
|
mov ds,ax ; to global's DS
|
|
mov cx,wGMTemp1
|
|
pop ds ; then back to parm's DS
|
|
else
|
|
mov cx,wGMTemp1
|
|
endif
|
|
|
|
if _LDATA
|
|
mov ax, Word Ptr parm3_
|
|
else
|
|
mov ax, Word Ptr parm2_ ; get addend
|
|
endif
|
|
aloop:
|
|
adc [bx+si],ax
|
|
mov ax,dx
|
|
inc bx
|
|
inc bx
|
|
loop aloop
|
|
|
|
rcl dx,1 ; save carry bit
|
|
or dx,0000h ; was max size number, if dx!=0
|
|
jz nout ; no bits shifted into carry
|
|
ifdef DSNOTHING
|
|
push ds ; save parm1's DS and switch
|
|
mov ax, seg wGMTemp1
|
|
mov ds,ax ; to global's DS
|
|
inc wGMTemp1 ; otherwise, one more int in number
|
|
cmp wGMTemp1,5 ; if working with 5-int number
|
|
pop ds
|
|
else
|
|
inc wGMTemp1 ; otherwise, one more int in number
|
|
cmp wGMTemp1,5 ; if working with 5-int number
|
|
endif
|
|
jg overf ;overflow: too many digits
|
|
|
|
mov [bx+si],dx
|
|
|
|
;
|
|
; If no overflow, see if we have mult'd # times requested
|
|
;
|
|
nout:
|
|
test [si+8],8000h ; see if high-order word set sign
|
|
jnz overf
|
|
gexit:
|
|
mov ax,GM_SUCCESS
|
|
exit:
|
|
if _LDATA
|
|
pop es
|
|
pop ds
|
|
endif
|
|
cproce
|
|
overf:
|
|
mov ax,GM_OVERFLOW ; here only on overflow
|
|
jmp short exit
|
|
;
|
|
; if the msd > 0ccch, or if = 0ccch and the high-order hex
|
|
; digit of msd -1 > hex c then overflow will occur, otherwise
|
|
; it won't
|
|
;
|
|
tstover:
|
|
cmp ax,0ccch ; overflow if sign sets during the
|
|
jg overf
|
|
jmp ct ; no overflow possible
|
|
endps
|
|
END
|