⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 misc7086.asm

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 ASM
字号:
;/****************************************************************************
;*
;*                            Open Watcom Project
;*
;*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
;*
;*  ========================================================================
;*
;*    This file contains Original Code and/or Modifications of Original
;*    Code as defined in and that are subject to the Sybase Open Watcom
;*    Public License version 1.0 (the 'License'). You may not use this file
;*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
;*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
;*    provided with the Original Code and Modifications, and is also
;*    available at www.sybase.com/developer/opensource.
;*
;*    The Original Code and all software distributed under the License are
;*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
;*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
;*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
;*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
;*    NON-INFRINGEMENT. Please see the License for the specific language
;*    governing rights and limitations under the License.
;*
;*  ========================================================================
;*
;* Description:  FPU related routines - read/write FPU state, get FPU type
;*                       16-bit version
;*
;****************************************************************************/


_TEXT segment byte public 'CODE'

ifndef __WINDOWS__

        public  "C", NPXType
NPXType proc    near
        push    bp                      ; save bp
        sub     ax,ax                   ; set initial control word to 0
        push    ax                      ; push it on stack
        mov     bp,sp                   ; point to control word
        finit                           ; initialize math coprocessor
        fstcw   [bp]                    ; store control word in memory
        fwait
        mov     al,0                    ; assume no coprocessor present
        mov     ah,[bp + 1]             ; upper byte is 03h if
        cmp     ah,03h                  ;   coprocessor is present
        jne     exit                    ; exit if no coprocessor present
        mov     al,1                    ; assume it is an 8087
        and     word ptr [bp],NOT 80h   ; turn interrupts on (IEM=0)
        fldcw   [bp]                    ; load control word
        fdisi                           ; disable interrupts (IEM=1)
        fstcw   [bp]                    ; store control word
        fwait
        test    word ptr [bp],80h       ; if IEM=1, then 8087
        jnz     exit                    ;
        finit                           ; use default infinity mode
        fld1                            ; generate infinity by
        fldz                            ;   dividing 1 by 0
        fdiv                            ; ...
        fld     st                      ; form negative infinity
        fchs                            ; ...
        fcompp                          ; compare +/- infinity
        fstsw   [bp]                    ; equal for 87/287
        fwait                           ; wait fstsw to complete
        mov     ax,[bp]                 ; get NDP control word
        mov     al,2                    ; assume 80287
        sahf                            ; store condition bits in flags
        jz      exit                    ; it's 287 if infinities equal
        mov     al,3                    ; indicate 80387
exit:   cbw                             ; zero ah
        fninit                          ; initialize math coprocessor
        pop     bp                      ; throw away control word
        pop     bp                      ; restore bp
        ret                             ; return
NPXType endp

endif

        public  "C", FPUExpand
FPUExpand  proc    near
        push    ds
        push    es
        push    si
        push    di
        push    cx
        mov     ds,dx
        mov     es,dx
        mov     si,ax
        std
        lea     di,[si + 28 + 80 - 1]
        lea     si,[si + 14 + 80 - 1]
        mov     cx,80
        rep     movsb
        xor     ax,ax
        mov     cx,6
loop1:  stosw
        movsw
        loop    loop1
        stosw
        cld
        pop     cx
        pop     di
        pop     si
        pop     es
        pop     ds
        ret
FPUExpand  endp

        public  "C", FPUContract
FPUContract  proc    near
        push    ds
        push    es
        push    si
        push    di
        push    cx
        mov     ds,dx
        mov     es,dx
        mov     si,ax
        lea     di,[si + 2]
        lea     si,[si + 4]
        mov     cx,6
loop2:  movsw
        add     si,2
        loop    loop2
        mov     cx,80
        rep     movsb
        pop     cx
        pop     di
        pop     si
        pop     es
        pop     ds
        ret
FPUContract  endp

ifndef __OS2__

Read8087 PROC
        public  "C",Read8087
        push    ds
        push    bx
        mov     ds,dx
        mov     bx,ax
ifdef REAL_MODE
        fnsave  [bx]
else
        fsave   [bx]
        frstor  [bx]
endif
        fwait
        pop     bx
        pop     ds
        call    FPUExpand
        ret
Read8087 ENDP

Write8087 PROC
        public  "C",Write8087
        call    FPUContract
        push    ds
        push    bx
        mov     ds,dx
        mov     bx,ax
ifdef REAL_MODE
        fnrstor [bx]
else
        frstor  [bx]
endif
        fwait
        pop     bx
        pop     ds
        ret
Write8087 ENDP

comment ~
    These routines read/write the FPU or emulator state when we're on a 386
    or better. They're a bit wierd so here's a explanation. There are operand
    size overrides on the fnsave and fnrstor so that a real FPU will save the
    full 32-bit state (this code is in a 16-bit segment). The emulator does
    not respect the operand size, but since it always stores the full state
    anyway that's OK. However, the 32-bit emulator does not know how to decode
    a 16-bit addressing mode - it always interprets things as if they were in
    the 32-bit form. That means that the [bx] addressing mode gets interpreted
    as [edi], which is why there are "movzx edi,bx" instructions. before the
    coprocessor instructions.
~

ifndef REAL_MODE

Read387 PROC
        public  "C",Read387
        push    ds
        push    bx
        mov     ds,dx
        mov     bx,ax
        db      66H
        fnsave  ds:[bx]
        fwait
        db      66H
        fnrstor ds:[bx]
        fwait
        pop     bx
        pop     ds
        ret
Read387 ENDP

Write387 PROC
        public  "C",Write387
        push    ds
        push    bx
        mov     ds,dx
        mov     bx,ax
        db      66h
        fnrstor ds:[bx]
        fwait
        pop     bx
        pop     ds
        ret
Write387 endp

endif

endif

_TEXT           ENDS

                END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -