Category : C Source Code
Archive   : FRAC151S.ZIP
Filename : MPMATH_A.ASM

 
Output of file : MPMATH_A.ASM contained in archive : FRAC151S.ZIP

TITLE mpmath_a.asm (C) 1989, Mark C. Peterson, CompuServe [70441,3353]
SUBTTL All rights reserved.
;
; Code may be used in any program provided the author is credited
; either during program execution or in the documentation. Source
; code may be distributed only in combination with public domain or
; shareware source code. Source code may be modified provided the
; copyright notice and this message is left unchanged and all
; modifications are clearly documented.
;
; I would appreciate a copy of any work which incorporates this code,
; however this is optional.
;
; Mark C. Peterson
; 253 West St., H
; Planstville, CT 06479
; (203) 276-9474
;
; Note: Remark statements following floating point commands generally indicate
; the FPU stack contents after the command is completed.
;
; References:
; 80386/80286 Assembly Language Programming
; by William H. Murray, III and Chris H. Pappas
; Published by Osborne McGraw-Hill, 1986
;
;
;


IFDEF ??version
MASM51
QUIRKS
EMUL
ENDIF

.model medium, c


.data

extrn cpu:WORD


MP STRUC
Exp DW 0
Mant DD 0
MP ENDS


PUBLIC MPOverflow
MPOverflow DW 0

Ans MP
Double DQ ?


.code

.8086

fg2MP086 PROC x:DWORD, fg:WORD
mov ax, WORD PTR [x]
mov dx, WORD PTR [x+2]
mov cx, ax
or cx, dx
jz ExitFg2MP

mov cx, 1 SHL 14 + 30
sub cx, fg

or dx, dx
jns BitScanRight

or ch, 80h
not ax
not dx
add ax, 1
adc dx, 0

BitScanRight:
shl ax, 1
rcl dx, 1
dec cx
or dx, dx
jns BitScanRight

ExitFg2MP:
mov Ans.Exp, cx
mov WORD PTR Ans.Mant+2, dx
mov WORD PTR Ans.Mant, ax
lea ax, Ans
mov dx, ds
ret
fg2MP086 ENDP



MPcmp086 PROC uses si di, xExp:WORD, xMant:DWORD, yExp:WORD, yMant:DWORD
LOCAL Rev:WORD, Flag:WORD
mov Rev, 0
mov Flag, 0
mov ax, xExp
mov dx, WORD PTR [xMant]
mov si, WORD PTR [xMant+2]
mov bx, yExp
mov cx, WORD PTR [yMant]
mov di, WORD PTR [yMant+2]
or ax, ax
jns AtLeastOnePos

or bx, bx
jns AtLeastOnePos

mov Rev, 1
and ah, 7fh
and bh, 7fh

AtLeastOnePos:
cmp ax, bx
jle Cmp1

mov Flag, 1
jmp ChkRev

Cmp1:
je Cmp2

mov Flag, -1
jmp ChkRev

Cmp2:
cmp si, di
jbe Cmp3

mov Flag, 1
jmp ChkRev

Cmp3:
je Cmp4

mov Flag, -1
jmp ChkRev

Cmp4:
cmp dx, cx
jbe Cmp5

mov Flag, 1
jmp ChkRev

Cmp5:
je ChkRev

mov Flag, -1

ChkRev:
or Rev, 0
jz ExitCmp

neg Flag

ExitCmp:
mov ax, Flag
ret
MPcmp086 ENDP






MPmul086 PROC uses si di, xExp:WORD, xMant:DWORD, yExp:WORD, yMant:DWORD
mov ax, xExp
mov bx, yExp
xor ch, ch
shl bh, 1
rcr ch, 1
shr bh, 1
xor ah, ch

sub bx, (1 SHL 14) - 2
add ax, bx
jno NoOverflow

Overflow:
or WORD PTR [xMant+2], 0
jz ZeroAns
or WORD PTR [yMant+2], 0
jz ZeroAns

mov MPOverflow, 1

ZeroAns:
xor ax, ax
xor dx, dx
mov Ans.Exp, ax
jmp StoreMant

NoOverflow:
mov Ans.Exp, ax

mov si, WORD PTR [xMant+2]
mov bx, WORD PTR [xMant]
mov di, WORD PTR [yMant+2]
mov cx, WORD PTR [yMant]

mov ax, si
or ax, bx
jz ZeroAns

mov ax, di
or ax, cx
jz ZeroAns

mov ax, cx
mul bx
push dx

mov ax, cx
mul si
push ax
push dx

mov ax, bx
mul di
push ax
push dx

mov ax, si
mul di
pop bx
pop cx
pop si
pop di

add ax, bx
adc dx, 0
pop bx
add di, bx
adc ax, 0
adc dx, 0
add di, cx
adc ax, si
adc dx, 0

or dx, dx
js StoreMant

shl di, 1
rcl ax, 1
rcl dx, 1
sub Ans.Exp, 1
jo Overflow

StoreMant:
mov WORD PTR Ans.Mant+2, dx
mov WORD PTR Ans.Mant, ax

lea ax, Ans
mov dx, ds
ret
MPmul086 ENDP



d2MP086 PROC uses si di, x:QWORD
mov dx, WORD PTR [x+6]
mov ax, WORD PTR [x+4]
mov bx, WORD PTR [x+2]
mov cx, WORD PTR [x]
mov si, dx
shl si, 1
or si, bx
or si, ax
or si, dx
or si, cx
jnz NonZero

xor ax, ax
xor dx, dx
jmp StoreAns

NonZero:
mov si, dx
shl si, 1
pushf
mov cl, 4
shr si, cl
popf
rcr si, 1
add si, (1 SHL 14) - (1 SHL 10)

mov di, ax ; shl dx:ax:bx 12 bits
mov cl, 12
shl dx, cl
shl ax, cl
mov cl, 4
shr di, cl
shr bx, cl
or dx, di
or ax, bx
stc
rcr dx, 1
rcr ax, 1

StoreAns:
mov Ans.Exp, si
mov WORD PTR Ans.Mant+2, dx
mov WORD PTR Ans.Mant, ax

lea ax, Ans
mov dx, ds
ret
d2MP086 ENDP



MP2d086 PROC uses si di, xExp:WORD, xMant:DWORD
sub xExp, (1 SHL 14) - (1 SHL 10)
jo Overflow

mov bx, xExp
and bx, 0111100000000000b
jz InRangeOfDouble

Overflow:
mov MPOverflow, 1
xor ax, ax
xor dx, dx
xor bx, bx
jmp StoreAns

InRangeOfDouble:
mov si, xExp
mov ax, si
mov cl, 5
shl si, cl
shl ax, 1
rcr si, 1

mov dx, WORD PTR [xMant+2]
mov ax, WORD PTR [xMant]
shl ax, 1
rcl dx, 1

mov bx, ax
mov di, dx
mov cl, 12
shr dx, cl
shr ax, cl
mov cl, 4
shl bx, cl
shl di, cl
or ax, di
or dx, si

StoreAns:
mov WORD PTR Double+6, dx
mov WORD PTR Double+4, ax
mov WORD PTR Double+2, bx
xor bx, bx
mov WORD PTR Double, bx

lea ax, Double
mov dx, ds
ret
MP2d086 ENDP




MPadd086 PROC uses si di, xExp:WORD, xMant:DWORD, yExp:WORD, yMant:DWORD
mov si, xExp
mov dx, WORD PTR [xMant+2]
mov ax, WORD PTR [xMant]

mov di, yExp

mov cx, si
xor cx, di
js Subtract
jz SameMag

cmp si, di
jg XisGreater

xchg si, di
xchg dx, WORD PTR [yMant+2]
xchg ax, WORD PTR [yMant]

XisGreater:
mov cx, si
sub cx, di
cmp cx, 32
jl ChkSixteen
jmp StoreAns

ChkSixteen:
cmp cx, 16
jl SixteenBitShift

sub cx, 16
mov bx, WORD PTR [yMant+2]
shr bx, cl
mov WORD PTR [yMant], bx
mov WORD PTR [yMant+2], 0
jmp SameMag

SixteenBitShift:
mov bx, WORD PTR [yMant+2]
shr WORD PTR [yMant+2], cl
shr WORD PTR [yMant], cl
neg cl
add cl, 16
shl bx, cl
or WORD PTR [yMant], bx

SameMag:
add ax, WORD PTR [yMant]
adc dx, WORD PTR [yMant+2]
jc ShiftCarry
jmp StoreAns

ShiftCarry:
rcr dx, 1
rcr ax, 1
add si, 1
jo Overflow
jmp StoreAns

Overflow:
mov MPOverflow, 1

ZeroAns:
xor si, si
xor ax, ax
xor dx, dx
jmp StoreAns

Subtract:
xor di, 8000h
mov cx, si
sub cx, di
jnz DifferentMag

cmp dx, WORD PTR [yMant+2]
jg SubtractNumbers
jne SwapNumbers

cmp ax, WORD PTR [yMant]
jg SubtractNumbers
je ZeroAns

SwapNumbers:
xor si, 8000h
xchg ax, WORD PTR [yMant]
xchg dx, WORD PTR [yMant+2]
jmp SubtractNumbers

DifferentMag:
or cx, cx
jns NoSwap

xchg si, di
xchg ax, WORD PTR [yMant]
xchg dx, WORD PTR [yMant+2]
xor si, 8000h
neg cx

NoSwap:
cmp cx, 32
jge StoreAns

cmp cx, 16
jl SixteenBitShift2

sub cx, 16
mov bx, WORD PTR [yMant+2]
shr bx, cl
mov WORD PTR [yMant], bx
mov WORD PTR [yMant+2], 0
jmp SubtractNumbers

SixteenBitShift2:
mov bx, WORD PTR [yMant+2]
shr WORD PTR [yMant+2], cl
shr WORD PTR [yMant], cl
neg cl
add cl, 16
shl bx, cl
or WORD PTR [yMant], bx

SubtractNumbers:
sub ax, WORD PTR [yMant]
sbb dx, WORD PTR [yMant+2]

BitScanRight:
or dx, dx
js StoreAns

shl ax, 1
rcl dx, 1
sub si, 1
jno BitScanRight
jmp Overflow

StoreAns:
mov Ans.Exp, si
mov WORD PTR Ans.Mant+2, dx
mov WORD PTR Ans.Mant, ax

lea ax, Ans
mov dx, ds
ret
MPadd086 ENDP



MPdiv086 PROC uses si di, xExp:WORD, xMant:DWORD, yExp:WORD, \
yMant:DWORD
mov ax, xExp
mov bx, yExp
xor ch, ch
shl bh, 1
rcr ch, 1
shr bh, 1
xor ah, ch

sub bx, (1 SHL 14) - 2
sub ax, bx
jno NoOverflow

Overflow:
mov MPOverflow, 1

ZeroAns:
xor ax, ax
xor dx, dx
mov Ans.Exp, dx
jmp StoreMant

NoOverflow:
mov Ans.Exp, ax

mov dx, WORD PTR [xMant+2]
mov ax, WORD PTR [xMant]
or dx, dx
jz ZeroAns

mov cx, WORD PTR [yMant+2]
mov bx, WORD PTR [yMant]
or cx, cx
jz Overflow

cmp dx, cx
jl Divide

shr dx, 1
rcr ax, 1
add Ans.Exp, 1
jo Overflow

Divide:
div cx
mov si, dx
mov dx, bx
mov bx, ax
mul dx
xor di, di
cmp dx, si
jnc RemReallyNeg

xchg ax, di
xchg dx, si
sub ax, di
sbb dx, si

shr dx, 1
rcr ax, 1
div cx
mov dx, bx
shl ax, 1
adc dx, 0
jmp StoreMant

RemReallyNeg:
sub ax, di
sbb dx, si

shr dx, 1
rcr ax, 1
div cx
mov dx, bx
mov bx, ax
xor ax, ax
xor cx, cx
shl bx, 1
rcl cx, 1
sub ax, bx
sbb dx, cx
jno StoreMant

shl ax, 1
rcl dx, 1
dec Ans.Exp

StoreMant:
mov WORD PTR Ans.Mant, ax
mov WORD PTR Ans.Mant+2, dx
lea ax, Ans
mov dx, ds
ret
MPdiv086 ENDP


MPcmp386 PROC uses si di, xExp:WORD, xMant:DWORD, yExp:WORD, yMant:DWORD
mov si, 0
mov di, si
.386
mov ax, xExp
mov edx, xMant
mov bx, yExp
mov ecx, yMant
or ax, ax
jns AtLeastOnePos

or bx, bx
jns AtLeastOnePos

mov si, 1
and ah, 7fh
and bh, 7fh

AtLeastOnePos:
cmp ax, bx
jle Cmp1

mov di, 1
jmp ChkRev

Cmp1:
je Cmp2

mov di, -1
jmp ChkRev

Cmp2:
cmp edx, ecx
jbe Cmp3

mov di, 1
jmp ChkRev

Cmp3:
je ChkRev

mov di, -1

ChkRev:
or si, si
jz ExitCmp

neg di

ExitCmp:
mov ax, di
.8086
ret
MPcmp386 ENDP



d2MP386 PROC uses si di, x:QWORD
mov si, WORD PTR [x+6]
.386
mov edx, DWORD PTR [x+4]
mov eax, DWORD PTR [x]

mov ebx, edx
shl ebx, 1
or ebx, eax
jnz NonZero

xor si, si
xor edx, edx
jmp StoreAns

NonZero:
shl si, 1
pushf
shr si, 4
popf
rcr si, 1
add si, (1 SHL 14) - (1 SHL 10)

shld edx, eax, 12
stc
rcr edx, 1

StoreAns:
mov Ans.Exp, si
mov Ans.Mant, edx

lea ax, Ans
mov dx, ds
.8086
ret
d2MP386 ENDP




MP2d386 PROC uses si di, xExp:WORD, xMant:DWORD
sub xExp, (1 SHL 14) - (1 SHL 10)
.386
jo Overflow

mov bx, xExp
and bx, 0111100000000000b
jz InRangeOfDouble

Overflow:
mov MPOverflow, 1
xor eax, eax
xor edx, edx
jmp StoreAns

InRangeOfDouble:
mov bx, xExp
mov ax, bx
shl bx, 5
shl ax, 1
rcr bx, 1
shr bx, 4

mov edx, xMant
shl edx, 1
xor eax, eax
shrd eax, edx, 12
shrd edx, ebx, 12

StoreAns:
mov DWORD PTR Double+4, edx
mov DWORD PTR Double, eax

lea ax, Double
mov dx, ds
.8086
ret
MP2d386 ENDP



MPmul386 PROC uses si di, xExp:WORD, xMant:DWORD, yExp:WORD, \
yMant:DWORD
mov ax, xExp
mov bx, yExp
.386
xor ch, ch
shl bh, 1
rcr ch, 1
shr bh, 1
xor ah, ch

sub bx, (1 SHL 14) - 2
add ax, bx
jno NoOverflow

Overflow:
or WORD PTR [xMant+2], 0
jz ZeroAns
or WORD PTR [yMant+2], 0
jz ZeroAns

mov MPOverflow, 1

ZeroAns:
xor edx, edx
mov Ans.Exp, dx
jmp StoreMant

NoOverflow:
mov Ans.Exp, ax

mov eax, xMant
mov edx, yMant
or eax, eax
jz ZeroAns

or edx, edx
jz ZeroAns

mul edx

or edx, edx
js StoreMant

shld edx, eax, 1
sub Ans.Exp, 1
jo Overflow

StoreMant:
mov Ans.Mant, edx
lea ax, Ans
mov dx, ds
.8086
ret
MPmul386 ENDP



MPadd386 PROC uses si di, xExp:WORD, xMant:DWORD, yExp:WORD, \
yMant:DWORD
mov si, xExp
.386
mov eax, xMant

mov di, yExp
mov edx, yMant

mov cx, si
xor cx, di
js Subtract
jz SameMag

cmp si, di
jg XisGreater

xchg si, di
xchg eax, edx

XisGreater:
mov cx, si
sub cx, di
cmp cx, 32
jge StoreAns

shr edx, cl

SameMag:
add eax, edx
jnc StoreAns

rcr eax, 1
add si, 1
jno StoreAns

Overflow:
mov MPOverflow, 1

ZeroAns:
xor si, si
xor edx, edx
jmp StoreAns

Subtract:
xor di, 8000h
mov cx, si
sub cx, di
jnz DifferentMag

cmp eax, edx
jg SubtractNumbers
je ZeroAns

xor si, 8000h
xchg eax, edx
jmp SubtractNumbers

DifferentMag:
or cx, cx
jns NoSwap

xchg si, di
xchg eax, edx
xor si, 8000h
neg cx

NoSwap:
cmp cx, 32
jge StoreAns

shr edx, cl

SubtractNumbers:
sub eax, edx
bsr ecx, eax
neg cx
add cx, 31
shl eax, cl
sub si, cx
jo Overflow

StoreAns:
mov Ans.Exp, si
mov Ans.Mant, eax

lea ax, Ans
mov dx, ds
.8086
ret
MPadd386 ENDP





MPdiv386 PROC uses si di, xExp:WORD, xMant:DWORD, yExp:WORD, \
yMant:DWORD
mov ax, xExp
mov bx, yExp
.386
xor ch, ch
shl bh, 1
rcr ch, 1
shr bh, 1
xor ah, ch

sub bx, (1 SHL 14) - 2
sub ax, bx
jno NoOverflow

Overflow:
mov MPOverflow, 1

ZeroAns:
xor eax, eax
mov Ans.Exp, ax
jmp StoreMant

NoOverflow:
mov Ans.Exp, ax

xor eax, eax
mov edx, xMant
mov ecx, yMant
or edx, edx
jz ZeroAns

or ecx, ecx
jz Overflow

cmp edx, ecx
jl Divide

shr edx, 1
rcr eax, 1
add Ans.Exp, 1
jo Overflow

Divide:
div ecx

StoreMant:
mov Ans.Mant, eax
lea ax, Ans
mov dx, ds
.8086
ret
MPdiv386 ENDP


fg2MP386 PROC x:DWORD, fg:WORD
mov bx, 1 SHL 14 + 30
sub bx, fg
.386
mov edx, x

or edx, edx
jnz ChkNegMP

mov bx, dx
jmp StoreAns

ChkNegMP:
jns BitScanRight

or bh, 80h
neg edx

BitScanRight:
bsr ecx, edx
neg cx
add cx, 31
sub bx, cx
shl edx, cl

StoreAns:
mov Ans.Exp, bx
mov Ans.Mant, edx
.8086
lea ax, Ans
mov dx, ds
ret
fg2MP386 ENDP



PUBLIC MPcmp, MPmul, MPadd, MPdiv, MP2d, d2MP, fg2MP

fg2MP:
cmp cpu, 386
je Use386fg2MP
jmp fg2MP086

Use386fg2MP:
jmp fg2MP386

MPcmp:
cmp cpu, 386
je Use386cmp
jmp MPcmp086

Use386cmp:
jmp MPcmp386

MPmul:
cmp cpu, 386
je Use386mul
jmp MPmul086

Use386mul:
jmp MPmul386

d2MP:
cmp cpu, 386
je Use386d2MP
jmp d2MP086

Use386d2MP:
jmp d2MP386

MPadd:
cmp cpu, 386
je Use386add
jmp MPadd086

Use386add:
jmp MPadd386

MPdiv:
cmp cpu, 386
je Use386div
jmp MPdiv086

Use386div:
jmp MPdiv386

MP2d:
cmp cpu, 386
je Use386MP2d
jmp MP2d086

Use386MP2d:
jmp MP2d386


END