FLDENV FSTENV FSTOR FSAVE added.status word can now be examined. closes #998201
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1752
This commit is contained in:
parent
229e81304b
commit
c7ab4990a0
2 changed files with 90 additions and 12 deletions
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: fpu.cpp,v 1.18 2004-03-29 18:03:02 qbix79 Exp $ */
|
||||
/* $Id: fpu.cpp,v 1.19 2004-04-01 08:57:33 qbix79 Exp $ */
|
||||
|
||||
#include "dosbox.h"
|
||||
#if C_FPU
|
||||
|
@ -61,6 +61,20 @@ INLINE void FPU_SetCW(Bitu word) {
|
|||
fpu.ex_mask = word & 0x3f;
|
||||
}
|
||||
|
||||
static Bit16u FPU_GetTag(void){
|
||||
Bit16u tag=0;
|
||||
for(Bitu i=0;i<8;i++)
|
||||
tag |= ( (fpu.tags[i]&3) <<(2*i));
|
||||
return tag;
|
||||
}
|
||||
|
||||
static void FPU_SetTag(Bit16u tag)
|
||||
{
|
||||
for(Bitu i=0;i<8;i++)
|
||||
fpu.tags[i]= static_cast<FPU_Tag>((tag >>(2*i))&3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
INLINE Bitu FPU_GET_TOP(void){
|
||||
|
@ -234,12 +248,18 @@ void FPU_ESC1_EA(Bitu rm,PhysPt addr) {
|
|||
}
|
||||
FPU_FPOP();
|
||||
break;
|
||||
case 0x05: /*FLDCW */
|
||||
case 0x04: /* FLDENV */
|
||||
FPU_FLDENV(addr);
|
||||
break;
|
||||
case 0x05: /* FLDCW */
|
||||
{
|
||||
Bit16u temp =mem_readw(addr);
|
||||
FPU_SetCW(temp);
|
||||
}
|
||||
break;
|
||||
case 0x06: /* FSTENV */
|
||||
FPU_FSTENV(addr);
|
||||
break;
|
||||
case 0x07: /* FNSTCW*/
|
||||
mem_writew(addr,fpu.cw);
|
||||
break;
|
||||
|
@ -432,10 +452,13 @@ void FPU_ESC3_EA(Bitu rm,PhysPt addr) {
|
|||
FPU_FPOP();
|
||||
break;
|
||||
case 0x05: /* FLD 80 Bits Real */
|
||||
FPU_FLD80(addr);
|
||||
{
|
||||
Real64 val = FPU_FLD80(addr);
|
||||
FPU_PUSH(val);
|
||||
}
|
||||
break;
|
||||
case 0x07: /* FSTP 80 Bits Real */
|
||||
FPU_ST80(addr);
|
||||
FPU_ST80(addr,TOP);
|
||||
FPU_FPOP();
|
||||
break;
|
||||
default:
|
||||
|
@ -461,7 +484,7 @@ void FPU_ESC3_Normal(Bitu rm) {
|
|||
break;
|
||||
case 0x04: //FNSETPM
|
||||
case 0x05: //FRSTPM
|
||||
LOG(LOG_FPU,LOG_ERROR)("80267 protected mode (un)set. Nothing done");
|
||||
// LOG(LOG_FPU,LOG_ERROR)("80267 protected mode (un)set. Nothing done");
|
||||
FPU_FNOP();
|
||||
break;
|
||||
default:
|
||||
|
@ -543,6 +566,12 @@ void FPU_ESC5_EA(Bitu rm,PhysPt addr) {
|
|||
mem_writed(addr+4,fpu.regs[TOP].l.upper);
|
||||
FPU_FPOP();
|
||||
break;
|
||||
case 0x04: /* FSTOR */
|
||||
FPU_FSTOR(addr);
|
||||
break;
|
||||
case 0x06: /* FSAVE */
|
||||
FPU_FSAVE(addr);
|
||||
break;
|
||||
case 0x07: /*FNSTSW NG DISAGREES ON THIS*/
|
||||
FPU_SET_TOP(TOP);
|
||||
mem_writew(addr,fpu.sw);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: fpu_instructions.h,v 1.16 2004-01-11 09:41:52 qbix79 Exp $ */
|
||||
/* $Id: fpu_instructions.h,v 1.17 2004-04-01 08:57:33 qbix79 Exp $ */
|
||||
|
||||
|
||||
static void FPU_FINIT(void) {
|
||||
|
@ -265,7 +265,7 @@ static void FPU_FBST(PhysPt addr)
|
|||
#define BIAS80 16383
|
||||
#define BIAS64 1023
|
||||
|
||||
static void FPU_FLD80(PhysPt addr)
|
||||
static Real64 FPU_FLD80(PhysPt addr)
|
||||
{
|
||||
struct{
|
||||
Bit16s begin;
|
||||
|
@ -283,20 +283,21 @@ static void FPU_FLD80(PhysPt addr)
|
|||
Bit64s sign = (test.begin &0x8000)?1:0;
|
||||
FPU_Reg result;
|
||||
result.ll= (sign <<63)|(exp64final << 52)| mant64;
|
||||
FPU_PUSH(result.d);
|
||||
return result.d;
|
||||
|
||||
//mant64= test.mant80/2***64 * 2 **53
|
||||
}
|
||||
|
||||
static void FPU_ST80(PhysPt addr)
|
||||
static void FPU_ST80(PhysPt addr,Bitu reg)
|
||||
{
|
||||
struct{
|
||||
Bit16s begin;
|
||||
FPU_Reg eind;
|
||||
} test;
|
||||
Bit64s sign80= (fpu.regs[TOP].ll&LONGTYPE(0x8000000000000000))?1:0;
|
||||
Bit64s exp80 = fpu.regs[TOP].ll&LONGTYPE(0x7ff0000000000000);
|
||||
Bit64s sign80= (fpu.regs[reg].ll&LONGTYPE(0x8000000000000000))?1:0;
|
||||
Bit64s exp80 = fpu.regs[reg].ll&LONGTYPE(0x7ff0000000000000);
|
||||
Bit64s exp80final= (exp80>>52) - BIAS64 + BIAS80;
|
||||
Bit64s mant80 = fpu.regs[TOP].ll&LONGTYPE(0x000fffffffffffff);
|
||||
Bit64s mant80 = fpu.regs[reg].ll&LONGTYPE(0x000fffffffffffff);
|
||||
Bit64s mant80final= (mant80 << 11) | LONGTYPE(0x8000000000000000);
|
||||
test.begin= (static_cast<Bit16s>(sign80)<<15)| static_cast<Bit16s>(exp80final);
|
||||
test.eind.ll=mant80final;
|
||||
|
@ -320,3 +321,51 @@ static void FPU_FSCALE(void){
|
|||
return; //2^x where x is chopped.
|
||||
}
|
||||
|
||||
static void FPU_FSTENV(PhysPt addr){
|
||||
if(!cpu.code.big) {
|
||||
mem_writew(addr+0,static_cast<Bit16u>(fpu.cw));
|
||||
mem_writew(addr+2,static_cast<Bit16u>(fpu.sw));
|
||||
mem_writew(addr+4,static_cast<Bit16u>(FPU_GetTag()));
|
||||
} else {
|
||||
mem_writed(addr+0,static_cast<Bit32u>(fpu.cw));
|
||||
mem_writed(addr+4,static_cast<Bit32u>(fpu.sw));
|
||||
mem_writed(addr+8,static_cast<Bit32u>(FPU_GetTag()));
|
||||
}
|
||||
}
|
||||
|
||||
static void FPU_FLDENV(PhysPt addr){
|
||||
Bit16u tag;
|
||||
Bit32u tagbig;
|
||||
Bitu cw;
|
||||
if(!cpu.code.big) {
|
||||
cw = mem_readw(addr+0);
|
||||
fpu.sw = mem_readw(addr+2);
|
||||
tag = mem_readw(addr+4);
|
||||
} else {
|
||||
cw = mem_readd(addr+0);
|
||||
fpu.sw = mem_readd(addr+4);
|
||||
tagbig = mem_readd(addr+8);
|
||||
tag = static_cast<Bit16u>(tagbig);
|
||||
}
|
||||
FPU_SetTag(tag);
|
||||
FPU_SetCW(cw);
|
||||
}
|
||||
|
||||
static void FPU_FSAVE(PhysPt addr){
|
||||
FPU_FSTENV(addr);
|
||||
Bitu start=(cpu.code.big?28:14);
|
||||
for(Bitu i=0;i<8;i++){
|
||||
FPU_ST80(addr+start,i);
|
||||
start+=10;
|
||||
}
|
||||
}
|
||||
|
||||
static void FPU_FSTOR(PhysPt addr){
|
||||
FPU_FLDENV(addr);
|
||||
Bitu start=(cpu.code.big?28:14);
|
||||
for(Bitu i=0;i<8;i++){
|
||||
fpu.regs[i].d=FPU_FLD80(addr+start);
|
||||
start+=10;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue