FPU copy should now work.

This commit is contained in:
TomW 2015-05-18 20:33:33 +01:00
commit 52a27a9256
7 changed files with 232 additions and 44 deletions

View file

@ -98,14 +98,15 @@ static int FSTOR()
eaaddr += 28;
break;
}
x87_ldmmx(&MM[0]); ST(0)=x87_ld80(); eaaddr += 10;
x87_ldmmx(&MM[1]); ST(1)=x87_ld80(); eaaddr += 10;
x87_ldmmx(&MM[2]); ST(2)=x87_ld80(); eaaddr += 10;
x87_ldmmx(&MM[3]); ST(3)=x87_ld80(); eaaddr += 10;
x87_ldmmx(&MM[4]); ST(4)=x87_ld80(); eaaddr += 10;
x87_ldmmx(&MM[5]); ST(5)=x87_ld80(); eaaddr += 10;
x87_ldmmx(&MM[6]); ST(6)=x87_ld80(); eaaddr += 10;
x87_ldmmx(&MM[7]); ST(7)=x87_ld80();
x87_ldmmx(&MM[0]); x87_ld_frstor(0); eaaddr += 10;
x87_ldmmx(&MM[1]); x87_ld_frstor(1); eaaddr += 10;
x87_ldmmx(&MM[2]); x87_ld_frstor(2); eaaddr += 10;
x87_ldmmx(&MM[3]); x87_ld_frstor(3); eaaddr += 10;
x87_ldmmx(&MM[4]); x87_ld_frstor(4); eaaddr += 10;
x87_ldmmx(&MM[5]); x87_ld_frstor(5); eaaddr += 10;
x87_ldmmx(&MM[6]); x87_ld_frstor(6); eaaddr += 10;
x87_ldmmx(&MM[7]); x87_ld_frstor(7);
ismmx = 0;
/*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times
something like this is needed*/
@ -160,14 +161,14 @@ static int FSAVE()
}
else
{
x87_st80(ST(0)); eaaddr+=10;
x87_st80(ST(1)); eaaddr+=10;
x87_st80(ST(2)); eaaddr+=10;
x87_st80(ST(3)); eaaddr+=10;
x87_st80(ST(4)); eaaddr+=10;
x87_st80(ST(5)); eaaddr+=10;
x87_st80(ST(6)); eaaddr+=10;
x87_st80(ST(7));
x87_st_fsave(0); eaaddr+=10;
x87_st_fsave(1); eaaddr+=10;
x87_st_fsave(2); eaaddr+=10;
x87_st_fsave(3); eaaddr+=10;
x87_st_fsave(4); eaaddr+=10;
x87_st_fsave(5); eaaddr+=10;
x87_st_fsave(6); eaaddr+=10;
x87_st_fsave(7);
}
break;
case 0x001: /*16-bit protected mode*/
@ -192,14 +193,14 @@ static int FSAVE()
}
else
{
x87_st80(ST(0)); eaaddr+=10;
x87_st80(ST(1)); eaaddr+=10;
x87_st80(ST(2)); eaaddr+=10;
x87_st80(ST(3)); eaaddr+=10;
x87_st80(ST(4)); eaaddr+=10;
x87_st80(ST(5)); eaaddr+=10;
x87_st80(ST(6)); eaaddr+=10;
x87_st80(ST(7));
x87_st_fsave(0); eaaddr+=10;
x87_st_fsave(1); eaaddr+=10;
x87_st_fsave(2); eaaddr+=10;
x87_st_fsave(3); eaaddr+=10;
x87_st_fsave(4); eaaddr+=10;
x87_st_fsave(5); eaaddr+=10;
x87_st_fsave(6); eaaddr+=10;
x87_st_fsave(7);
}
break;
case 0x100: /*32-bit real mode*/
@ -223,14 +224,14 @@ static int FSAVE()
}
else
{
x87_st80(ST(0)); eaaddr+=10;
x87_st80(ST(1)); eaaddr+=10;
x87_st80(ST(2)); eaaddr+=10;
x87_st80(ST(3)); eaaddr+=10;
x87_st80(ST(4)); eaaddr+=10;
x87_st80(ST(5)); eaaddr+=10;
x87_st80(ST(6)); eaaddr+=10;
x87_st80(ST(7));
x87_st_fsave(0); eaaddr+=10;
x87_st_fsave(1); eaaddr+=10;
x87_st_fsave(2); eaaddr+=10;
x87_st_fsave(3); eaaddr+=10;
x87_st_fsave(4); eaaddr+=10;
x87_st_fsave(5); eaaddr+=10;
x87_st_fsave(6); eaaddr+=10;
x87_st_fsave(7);
}
break;
case 0x101: /*32-bit protected mode*/
@ -255,14 +256,14 @@ static int FSAVE()
}
else
{
x87_st80(ST(0)); eaaddr+=10;
x87_st80(ST(1)); eaaddr+=10;
x87_st80(ST(2)); eaaddr+=10;
x87_st80(ST(3)); eaaddr+=10;
x87_st80(ST(4)); eaaddr+=10;
x87_st80(ST(5)); eaaddr+=10;
x87_st80(ST(6)); eaaddr+=10;
x87_st80(ST(7));
x87_st_fsave(0); eaaddr+=10;
x87_st_fsave(1); eaaddr+=10;
x87_st_fsave(2); eaaddr+=10;
x87_st_fsave(3); eaaddr+=10;
x87_st_fsave(4); eaaddr+=10;
x87_st_fsave(5); eaaddr+=10;
x87_st_fsave(6); eaaddr+=10;
x87_st_fsave(7);
}
break;
}
@ -306,10 +307,17 @@ static int opFSTSW_a32(uint32_t fetchdat)
static int opFLD(uint32_t fetchdat)
{
int old_tag;
uint64_t old_i64;
FP_ENTER();
pc++;
if (fplog) pclog("FLD %f\n", ST(fetchdat & 7));
old_tag = tag[(TOP + fetchdat) & 7];
old_i64 = ST_i64[(TOP + fetchdat) & 7];
x87_push(ST(fetchdat&7));
tag[TOP] = old_tag;
ST_i64[TOP] = old_i64;
CLOCK_CYCLES(4);
return 0;
}
@ -317,12 +325,21 @@ static int opFLD(uint32_t fetchdat)
static int opFXCH(uint32_t fetchdat)
{
double td;
uint8_t old_tag;
uint64_t old_i64;
FP_ENTER();
pc++;
if (fplog) pclog("FXCH\n");
td = ST(0);
ST(0) = ST(fetchdat&7);
ST(fetchdat&7) = td;
old_tag = tag[TOP];
tag[TOP] = tag[(TOP + fetchdat) & 7];
tag[(TOP + fetchdat) & 7] = old_tag;
old_i64 = ST_i64[TOP];
ST_i64[TOP] = ST_i64[(TOP + fetchdat) & 7];
ST_i64[(TOP + fetchdat) & 7] = old_i64;
CLOCK_CYCLES(4);
return 0;
}
@ -333,6 +350,7 @@ static int opFCHS(uint32_t fetchdat)
pc++;
if (fplog) pclog("FCHS\n");
ST(0) = -ST(0);
tag[TOP] &= ~TAG_UINT64;
CLOCK_CYCLES(6);
return 0;
}
@ -343,6 +361,7 @@ static int opFABS(uint32_t fetchdat)
pc++;
if (fplog) pclog("FABS %f\n", ST(0));
ST(0) = fabs(ST(0));
tag[TOP] &= ~TAG_UINT64;
CLOCK_CYCLES(3);
return 0;
}
@ -450,6 +469,7 @@ static int opF2XM1(uint32_t fetchdat)
pc++;
if (fplog) pclog("F2XM1\n");
ST(0) = pow(2.0, ST(0)) - 1.0;
tag[TOP] &= ~TAG_UINT64;
CLOCK_CYCLES(200);
return 0;
}
@ -460,6 +480,7 @@ static int opFYL2X(uint32_t fetchdat)
pc++;
if (fplog) pclog("FYL2X\n");
ST(1) = ST(1) * (log(ST(0)) / log(2.0));
tag[(TOP + 1) & 7] &= ~TAG_UINT64;
x87_pop();
CLOCK_CYCLES(250);
return 0;
@ -471,6 +492,7 @@ static int opFYL2XP1(uint32_t fetchdat)
pc++;
if (fplog) pclog("FYL2XP1\n");
ST(1) = ST(1) * (log(ST(0)+1.0) / log(2.0));
tag[(TOP + 1) & 7] &= ~TAG_UINT64;
x87_pop();
CLOCK_CYCLES(250);
return 0;
@ -482,6 +504,7 @@ static int opFPTAN(uint32_t fetchdat)
pc++;
if (fplog) pclog("FPTAN\n");
ST(0) = tan(ST(0));
tag[TOP] &= ~TAG_UINT64;
x87_push(1.0);
npxs &= ~C2;
CLOCK_CYCLES(235);
@ -494,6 +517,7 @@ static int opFPATAN(uint32_t fetchdat)
pc++;
if (fplog) pclog("FPATAN\n");
ST(1) = atan2(ST(1), ST(0));
tag[(TOP + 1) & 7] &= ~TAG_UINT64;
x87_pop();
CLOCK_CYCLES(250);
return 0;
@ -527,6 +551,7 @@ static int opFPREM(uint32_t fetchdat)
if (fplog) pclog("FPREM %f %f ", ST(0), ST(1));
temp64 = (int64_t)(ST(0) / ST(1));
ST(0) = ST(0) - (ST(1) * (double)temp64);
tag[TOP] &= ~TAG_UINT64;
if (fplog) pclog("%f\n", ST(0));
npxs &= ~(C0|C1|C2|C3);
if (temp64 & 4) npxs|=C0;
@ -542,6 +567,7 @@ static int opFSQRT(uint32_t fetchdat)
pc++;
if (fplog) pclog("FSQRT\n");
ST(0) = sqrt(ST(0));
tag[TOP] &= ~TAG_UINT64;
CLOCK_CYCLES(83);
return 0;
}
@ -554,6 +580,7 @@ static int opFSINCOS(uint32_t fetchdat)
if (fplog) pclog("FSINCOS\n");
td = ST(0);
ST(0) = sin(td);
tag[TOP] &= ~TAG_UINT64;
x87_push(cos(td));
npxs &= ~C2;
CLOCK_CYCLES(330);
@ -566,6 +593,7 @@ static int opFRNDINT(uint32_t fetchdat)
pc++;
if (fplog) pclog("FRNDINT %g ", ST(0));
ST(0) = (double)x87_fround(ST(0));
tag[TOP] &= ~TAG_UINT64;
if (fplog) pclog("%g\n", ST(0));
CLOCK_CYCLES(21);
return 0;
@ -579,6 +607,7 @@ static int opFSCALE(uint32_t fetchdat)
if (fplog) pclog("FSCALE\n");
temp64 = (int64_t)ST(1);
ST(0) = ST(0) * pow(2.0, (double)temp64);
tag[TOP] &= ~TAG_UINT64;
CLOCK_CYCLES(30);
return 0;
}
@ -589,6 +618,7 @@ static int opFSIN(uint32_t fetchdat)
pc++;
if (fplog) pclog("FSIN\n");
ST(0) = sin(ST(0));
tag[TOP] &= ~TAG_UINT64;
npxs &= ~C2;
CLOCK_CYCLES(300);
return 0;
@ -600,6 +630,7 @@ static int opFCOS(uint32_t fetchdat)
pc++;
if (fplog) pclog("FCOS\n");
ST(0) = cos(ST(0));
tag[TOP] &= ~TAG_UINT64;
npxs &= ~C2;
CLOCK_CYCLES(300);
return 0;