* smartlinking the units works now

* setjmp/longjmp -> dmpi_setjmp/dpmi_longjmp to solve systemunit
    conflict
This commit is contained in:
peter 1998-08-15 17:01:13 +00:00
parent b2e9bb2cf5
commit a16e265f27
2 changed files with 917 additions and 1031 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,9 @@
{ {
$Id$ $Id$
This file is part of the Free Pascal run time library. This file is part of the Free Pascal run time library.
Copyright (c) 1993,97 by Pierre Muller, Copyright (c) 1996-98 by Pierre Muller
member of the Free Pascal development team.
FPU Emulator support
See the file COPYING.FPC, included in this distribution, See the file COPYING.FPC, included in this distribution,
for details about the copyright. for details about the copyright.
@ -12,291 +13,213 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************} **********************************************************************}
{ Translated to FPK pascal by Pierre Muller,
without changing the fpu.s file }
{
/* Copyright (C) 1994, 1995 Charles Sandmann (sandmann@clio.rice.edu)
* FPU setup and emulation hooks for DJGPP V2.0
* This file maybe freely distributed, no warranty. */
this file has been translated from
npxsetup.c }
unit emu387; unit emu387;
interface
interface procedure npxsetup(prog_name : string);
procedure npxsetup(prog_name : string);
implementation
uses dxeload, dpmiexcp, strings;
type
emu_entry_type = function(exc : pexception_state) : longint;
var
_emu_entry : emu_entry_type;
procedure _control87(mask1,mask2 : word); implementation
begin uses
{/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */} dxeload,dpmiexcp,strings;
type
emu_entry_type = function(exc : pexception_state) : longint;
var
_emu_entry : emu_entry_type;
procedure _control87(mask1,mask2 : word);
begin
{ Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details }
{ from file cntrl87.s in src/libc/pc_hw/fpu } { from file cntrl87.s in src/libc/pc_hw/fpu }
asm asm
{ make room on stack } { make room on stack }
pushl %eax pushl %eax
fstcw (%esp) fstcw (%esp)
fwait fwait
popl %eax popl %eax
andl $0xffff, %eax andl $0xffff, %eax
{ OK; we have the old value ready } { OK; we have the old value ready }
movl mask2, %ecx movl mask2, %ecx
notl %ecx notl %ecx
andl %eax, %ecx /* the bits we want to keep */ andl %eax, %ecx /* the bits we want to keep */
movl mask2, %edx movl mask2, %edx
andl mask1, %edx /* the bits we want to change */ andl mask1, %edx /* the bits we want to change */
orl %ecx, %edx /* the new value */ orl %ecx, %edx /* the new value */
pushl %edx pushl %edx
fldcw (%esp) fldcw (%esp)
popl %edx popl %edx
end; end;
end; end;
{ the problem with the stack that is not cleared }
function emu_entry(exc : pexception_state) : longint;
{ the problem with the stack that is not cleared }
function emu_entry(exc : pexception_state) : longint;
begin
emu_entry:=_emu_entry(exc);
end;
function nofpsig( sig : longint) : longint;
const
last_eip : longint = 0;
var
res : longint;
begin
{if last_eip=djgpp_exception_state^.__eip then
begin begin
emu_entry:=_emu_entry(exc); writeln('emu call two times at same address');
end;
function nofpsig( sig : longint) : longint;
var res : longint;
const
last_eip : longint = 0;
begin
{if last_eip=djgpp_exception_state^.__eip then
begin
writeln('emu call two times at same address');
dpmi_set_coprocessor_emulation(1);
_raise(SIGFPE);
exit(0);
end; }
last_eip:=djgpp_exception_state^.__eip;
res:=emu_entry(djgpp_exception_state);
if res<>0 then
begin
writeln('emu call failed. res = ',res);
dpmi_set_coprocessor_emulation(1);
_raise(SIGFPE);
exit(0);
end;
longjmp(pjmprec(djgpp_exception_state)^, djgpp_exception_state^.__eax);
nofpsig:=0;
end;
var
prev_exit : pointer;
procedure restore_DPMI_fpu_state;
begin
exitproc:=prev_exit;
dpmi_set_coprocessor_emulation(1); dpmi_set_coprocessor_emulation(1);
writeln('Coprocessor restored '); _raise(SIGFPE);
{/* Enable Coprocessor, no exceptions */} exit(0);
end; }
last_eip:=djgpp_exception_state^.__eip;
res:=emu_entry(djgpp_exception_state);
if res<>0 then
begin
writeln('emu call failed. res = ',res);
dpmi_set_coprocessor_emulation(1);
_raise(SIGFPE);
exit(0);
end; end;
dpmi_longjmp(pdpmi_jmp_buf(djgpp_exception_state)^, djgpp_exception_state^.__eax);
nofpsig:=0;
end;
{ function _detect_80387 : boolean;[C];
var
prev_exit : pointer;
procedure restore_DPMI_fpu_state;
begin
exitproc:=prev_exit;
{ Enable Coprocessor, no exceptions }
dpmi_set_coprocessor_emulation(1);
{$ifdef SYSTEMDEBUG}
writeln('Coprocessor restored ');
{$endif}
end;
{ function _detect_80387 : boolean;
not used because of the underscore problem } not used because of the underscore problem }
{$L fpu.o } {$L fpu.o }
function getenv(const envvar:string):string; function getenv(const envvar:string):string;
{ Copied here, preserves uses Dos (PFV) } { Copied here, preserves uses Dos (PFV) }
var var
hp : ppchar; hp : ppchar;
hs, hs,
_envvar : string; _envvar : string;
eqpos,i : longint; eqpos : longint;
begin
_envvar:=upcase(envvar);
hp:=envp;
getenv:='';
while assigned(hp^) do
begin
hs:=strpas(hp^);
eqpos:=pos('=',hs);
if copy(hs,1,eqpos-1)=_envvar then
begin
getenv:=copy(hs,eqpos+1,255);
exit;
end;
hp:=hp+4;
end;
end;
procedure npxsetup(prog_name : string);
var
cp : string;
i : byte;
have_80387 : boolean;
emu_p : pointer;
const
veryfirst : boolean = True;
begin
cp:=getenv('387');
if (length(cp)>0) and (upcase(cp[1])='N') then
have_80387:=False
else
begin begin
_envvar:=upcase(envvar); dpmi_set_coprocessor_emulation(1);
hp:=envp; asm
getenv:=''; call __detect_80387
while assigned(hp^) do movb %al,have_80387
begin
hs:=strpas(hp^);
eqpos:=pos('=',hs);
if copy(hs,1,eqpos-1)=_envvar then
begin
getenv:=copy(hs,eqpos+1,255);
exit;
end;
hp:=hp+4;
end; end;
end; end;
if (length(cp)>0) and (upcase(cp[1])='Q') then
procedure npxsetup(prog_name : string);
var
cp : string;
i : byte;
have_80387 : boolean;
emu_p : pointer;
const
veryfirst : boolean = True;
begin begin
cp:=getenv('387'); if not have_80387 then
if (length(cp)>0) and (upcase(cp[1])='N') then write(stderr,'No ');
have_80387:=False writeln(stderr,'80387 detected.');
else
begin
dpmi_set_coprocessor_emulation(1);
asm
call __detect_80387
movb %al,have_80387
end;
end;
if (length(cp)>0) and (upcase(cp[1])='Q') then
begin
if not have_80387 then
write(stderr,'No ');
writeln(stderr,'80387 detected.');
end;
if have_80387 then
{/* mask all exceptions, except invalid operation */}
_control87($033e, $ffff)
else
begin
{/* Flags value 3 means coprocessor emulation, exceptions to us */}
if (dpmi_set_coprocessor_emulation(3)<>0) then
begin
writeln(stderr,'Warning: Coprocessor not present and DPMI setup failed!');
writeln(stderr,' If application attempts floating operations system may hang!');
end
else
begin
cp:=getenv('EMU387');
if length(cp)=0 then
begin
for i:=length(prog_name) downto 1 do
if (prog_name[i]='\') or (prog_name[i]='/') then
break;
if i>1 then
cp:=copy(prog_name,1,i);
cp:=cp+'wmemu387.dxe';
end;
emu_p:=dxe_load(cp);
_emu_entry:=emu_entry_type(emu_p);
if (emu_p=nil) then
begin
writeln(cp+' load failed !');
halt;
end;
if veryfirst then
begin
veryfirst:=false;
prev_exit:=exitproc;
exitproc:=@restore_DPMI_fpu_state;
end;
signal(SIGNOFP,@nofpsig);
end;
end;
end; end;
if have_80387 then
begin
{ mask all exceptions, except invalid operation }
_control87($033e, $ffff)
end
else
begin
{ Flags value 3 means coprocessor emulation, exceptions to us }
if (dpmi_set_coprocessor_emulation(3)<>0) then
begin
writeln(stderr,'Warning: Coprocessor not present and DPMI setup failed!');
writeln(stderr,' If application attempts floating operations system may hang!');
end
else
begin
cp:=getenv('EMU387');
if length(cp)=0 then
begin
for i:=length(prog_name) downto 1 do
if (prog_name[i]='\') or (prog_name[i]='/') then
break;
if i>1 then
cp:=copy(prog_name,1,i);
cp:=cp+'wmemu387.dxe';
end;
emu_p:=dxe_load(cp);
_emu_entry:=emu_entry_type(emu_p);
if (emu_p=nil) then
begin
writeln(cp+' load failed !');
halt;
end;
if veryfirst then
begin
veryfirst:=false;
prev_exit:=exitproc;
exitproc:=@restore_DPMI_fpu_state;
end;
signal(SIGNOFP,@nofpsig);
end;
end;
end;
begin begin
npxsetup(paramstr(0)); npxsetup(paramstr(0));
end. end.
{ {
$Log$ $Log$
Revision 1.7 1998-07-22 21:37:51 michael Revision 1.8 1998-08-15 17:01:14 peter
* smartlinking the units works now
* setjmp/longjmp -> dmpi_setjmp/dpmi_longjmp to solve systemunit
conflict
Revision 1.7 1998/07/22 21:37:51 michael
+ ENViron unknow, replaced by envp + ENViron unknow, replaced by envp
Revision 1.6 1998/07/21 12:06:56 carl Revision 1.6 1998/07/21 12:06:56 carl
* restored working version * restored working version
Revision 1.2 1998/03/26 12:23:17 peter
* emu387 doesn't uses dos anymore (getenv copied local)
* makefile compilation order changed
Revision 1.1.1.1 1998/03/25 11:18:42 root
* Restored version
Revision 1.6 1998/03/18 15:34:46 pierre
+ fpu state is restaured in excep_exit
less risk of problems
Revision 1.5 1998/02/05 17:24:09 pierre
* bug in assembler code
* changed default name to wmemu387.dxe
Revision 1.4 1998/02/05 17:04:59 pierre
* emulation is working with wmemu387.dxe
Revision 1.3 1998/01/26 11:57:34 michael
+ Added log at the end
Revision 1.2 1998/01/19 17:04:40 pierre
* bug in dxe loading corrected, emu still does not work !!
Revision 1.1 1998/01/16 16:53:15 pierre
emu387 is a program based on npxset from DJGPP
that loads the emu387.dxe if no FPU is present
or if the env var 387 is set to N
}
{
$Log$
Revision 1.7 1998-07-22 21:37:51 michael
+ ENViron unknow, replaced by envp
Revision 1.6 1998/07/21 12:06:56 carl
* restored working version
Revision 1.2 1998/03/26 12:23:17 peter
* emu387 doesn't uses dos anymore (getenv copied local)
* makefile compilation order changed
Revision 1.1.1.1 1998/03/25 11:18:42 root
* Restored version
Revision 1.6 1998/03/18 15:34:46 pierre
+ fpu state is restaured in excep_exit
less risk of problems
Revision 1.5 1998/02/05 17:24:09 pierre
* bug in assembler code
* changed default name to wmemu387.dxe
Revision 1.4 1998/02/05 17:04:59 pierre
* emulation is working with wmemu387.dxe
Revision 1.3 1998/01/26 11:57:34 michael
+ Added log at the end
Working file: rtl/dos/go32v2/emu387.pp
description:
----------------------------
revision 1.2
date: 1998/01/19 17:04:40; author: pierre; state: Exp; lines: +11 -2
* bug in dxe loading corrected, emu still does not work !!
----------------------------
revision 1.1
date: 1998/01/16 16:53:15; author: pierre; state: Exp;
emu387 is a program based on npxset from DJGPP
that loads the emu387.dxe if no FPU is present
or if the env var 387 is set to N
=============================================================================
} }