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
 |