; ; FPU.ASM (c) Rainer Schnitker 92,93 ; ; ; 387 utils ; .286 .model SMALL, C .data extrn emu_entry:PWORD extrn emu_sel:WORD extrn emu_esp:DWORD havei387 dw 0 .code ; ; DWORD emu_init( void ) : call emu387 to get copro struct ; ; emu should init exception vector 7 ; public C emu_init emu_init Proc C USES DI SI, .386 push gs mov eax,12345678H mov gs,emu_sel mov edx,emu_esp call pword ptr emu_entry ; convert eax = copro-struct in dx:ax mov edx,eax shr edx,16 and eax,dword ptr 0FFFFh pop gs .286 ret emu_init endp ; ; void emu_switch( WORD , WORD ) : call emu387, to change process status ; public C emu_switch emu_switch PROC C \ used_math :WORD , \ debugged :WORD .386 push gs mov gs,emu_sel movzx ecx,used_math movzx edx,debugged call pword ptr emu_entry pop gs .286 ret emu_switch endp ; ; void do_fnsave( unsigned fpu_struct ) ; public C do_fnsave do_fnsave PROC C \ fpu_struct :WORD .386 movzx eax,word ptr fpu_struct db 066H fnsave [eax] fwait .286 ret do_fnsave endp ; ; void do_frstor( unsigned fpu_struct ) ; public C do_frstor do_frstor PROC C \ fpu_struct :WORD .386 movzx eax,word ptr fpu_struct db 066H frstor [eax] fwait .286 ret do_frstor endp ; ; void do_fninit(void) ; public C do_fninit do_fninit PROC C fninit ret do_fninit endp public C npx_installed npx_installed PROC C USES SI, fninit ; set SW,CW,.. mov si, offset havei387 mov word ptr [si],5a5ah fnstsw [si] ; save SW cmp byte ptr [si],0 ; SW==0 ? jne no_i387 fnstcw [si] ; save CW mov ax,[si] ; check and ax,103fh ; cmp ax,3fh ; init ? jne no_i387 fld1 ; check for 387 fldz fdiv fld st fchs fcompp fstsw [si] mov ax,[si] sahf je no_i387 fninit ; 387 ok ,init fnstcw havei387 wait and havei387,0fffah fldcw havei387 mov ax,1 jmp short ende no_i387: mov ax,0 ende: ret npx_installed endp end