1
0
Fork 0

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:
Peter Veenstra 2004-04-01 08:57:33 +00:00
parent 229e81304b
commit c7ab4990a0
2 changed files with 90 additions and 12 deletions

View file

@ -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);

View file

@ -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;
}
}