        title   FALOG.ASM Calculate Common Antilog on 80x87
        page    55,132

; FALOG.ASM --- Calculate Common Antilog on 80x87
;
; Copyright (C) 1989 Ziff Davis Communications
; PC Magazine * Ray Duncan
;
; Call with:    ST(0)     = argument
;
; Returns:      ST(0)     = antilog to base 10
;
; Uses:         CPU registers are preserved; 
;               uses 3 cells of coprocessor stack
;
; Note:         To obtain natural antilog, replace
;               "fldl2t" instruction with "fldl2e".
;
; Make sure coprocessor has been properly initialized
; with a previous call to INIT87!

_TEXT   segment word public 'CODE'

        assume  cs:_TEXT

oldcw   equ     word ptr [bp-4]         ; original control word
newcw   equ     word ptr [bp-2]         ; new control word

        public  falog
falog   proc    near

        push    ax                      ; save registers and
        push    bp                      ; make stack frame
        mov     bp,sp                   ; for local variables
        sub     sp,4
        fldl2t                          ; load log2(10)
        fmulp   st(1),st(0)             ; log2(10) * argument
        fld     st(0)                   ; duplicate product
        fstcw   oldcw                   ; get old control word
        fwait                           ; wait till it arrives
        mov     ax,oldcw                ; change rounding mode
        and     ax,0f3ffh               ; field to "round down"
        or      ax,0400h
        mov     newcw,ax
        fldcw   newcw                   ; force rounding mode
        frndint                         ; get int part of product
        fldcw   oldcw                   ; restore old rounding mode
        fld     st(0)                   ; duplicate integer part
        fxch    st(2)                   ; get original product
        fsubrp  st(1),st(0)             ; find fractional part
        fld1
        fchs
        fxch    st(1)                   ; scale fractional part
        fscale
        fstp    st(1)                   ; discard coprocessor junk      
        f2xm1                           ; raise 2 to power-1
        fld1
        faddp   st(1),st(0)             ; correct for the -1
        fmul    st(0),st(0)             ; square result
        fscale                          ; scale by int part
        fstp    st(1)                   ; discard coprocessor junk
        add     sp,4                    ; discard local variables
        pop     bp                      ; restore registers and
        pop     ax                      ; return result in ST(0)
        ret

falog   endp

_TEXT   ends

        end

