PCem

changeset 50:35566d85aeeb

FPU opcode 0xd9 0xd8-0xdf are aliases for FSTP1. Doom v1.0 now works when FPU enabled. Fixed TAG manipulation on several instructions.
author TomW
date Sat Dec 14 11:31:37 2013 +0000
parents 65adf253efaa
children 8e106d6280de
files src/x87.c
diffstat 1 files changed, 20 insertions(+), 11 deletions(-) [+]
line diff
     1.1 --- a/src/x87.c	Thu Dec 12 18:16:22 2013 +0000
     1.2 +++ b/src/x87.c	Sat Dec 14 11:31:37 2013 +0000
     1.3 @@ -392,6 +392,7 @@
     1.4          double td;
     1.5          int64_t temp64;
     1.6          uint16_t tempw;
     1.7 +        int temp;
     1.8          if (mod==3)
     1.9          {
    1.10                  switch (rmdat32&0xFF)
    1.11 @@ -416,6 +417,12 @@
    1.12                          return;
    1.13                          case 0xD8: case 0xD9: case 0xDA: case 0xDB: /*Invalid, but apparently not illegal*/
    1.14                          case 0xDC: case 0xDD: case 0xDE: case 0xDF:
    1.15 +                        if (fplog) pclog("FSTP\n");
    1.16 +                        ST(rmdat32 & 7) = ST(0);
    1.17 +                        temp = (tag >> ((TOP & 7) << 1)) & 3;
    1.18 +                        tag &= ~(3 << (((TOP + rmdat32) & 7) << 1));
    1.19 +                        tag |= (temp << (((TOP + rmdat32) & 7) << 1));
    1.20 +                        x87_pop();
    1.21                          cycles-=3;
    1.22                          return;
    1.23                          case 0xE0: /*FCHS*/
    1.24 @@ -548,10 +555,11 @@
    1.25                          cycles-=330;
    1.26                          return;
    1.27                          case 0xFC: /*FRNDINT*/
    1.28 -                        if (fplog) pclog("FRNDINT\n");
    1.29 +                        if (fplog) pclog("FRNDINT %g ", ST(0));
    1.30  //                        pclog("FRNDINT %f %i ",ST(0),(npxc>>10)&3);
    1.31                          ST(0)=(double)x87_fround(ST(0));
    1.32  //                        pclog("%f\n",ST(0));
    1.33 +                        if (fplog) pclog("%g\n", ST(0));
    1.34                          cycles-=21;
    1.35                          return;
    1.36                          case 0xFD: /*FSCALE*/
    1.37 @@ -807,10 +815,11 @@
    1.38                          cycles-=28;
    1.39                          return;
    1.40                          case 3: /*FISTP short*/
    1.41 -                        if (fplog) pclog("FISTPs %08X:%08X\n", easeg, eaaddr);
    1.42 +                        if (fplog) pclog("FISTPs %08X:%08X  %g ", easeg, eaaddr, ST(0));
    1.43                          temp64 = x87_fround(ST(0));
    1.44  /*                        if (temp64 > 2147483647 || temp64 < -2147483647)
    1.45                             fatal("FISTPl out of range! %i\n", temp64);*/
    1.46 +                        if (fplog) pclog("%lli %llX\n", temp64, temp64);
    1.47                          seteal((int32_t)temp64); if (abrt) return;
    1.48                          x87_pop();
    1.49                          cycles-=28;
    1.50 @@ -953,23 +962,23 @@
    1.51                  {
    1.52                          case 0: /*FFREE*/
    1.53                          if (fplog) pclog("FFREE\n");
    1.54 -                        tag|=(3<<((rmdat32&7)<<1));
    1.55 +                        tag |= (3 << (((TOP + rmdat32) & 7) << 1));
    1.56                          cycles-=3;
    1.57                          return;
    1.58                          case 2: /*FST*/
    1.59                          if (fplog) pclog("FST\n");
    1.60 -                        ST(rmdat32&7)=ST(0);
    1.61 -                        temp=(tag>>((TOP&7)<<1))&3;
    1.62 -                        tag&=~(3<<((rmdat32&7)<<1));
    1.63 -                        tag|=(temp<<((rmdat32&7)<<1));
    1.64 +                        ST(rmdat32 & 7) = ST(0);
    1.65 +                        temp = (tag >> ((TOP & 7) << 1)) & 3;
    1.66 +                        tag &= ~(3 << (((TOP + rmdat32) & 7) << 1));
    1.67 +                        tag |= (temp << (((TOP + rmdat32) & 7) << 1));
    1.68                          cycles-=3;
    1.69                          return;
    1.70                          case 3: /*FSTP*/
    1.71                          if (fplog) pclog("FSTP\n");
    1.72 -                        ST(rmdat32&7)=ST(0);
    1.73 -                        temp=(tag>>((TOP&7)<<1))&3;
    1.74 -                        tag&=~(3<<((rmdat32&7)<<1));
    1.75 -                        tag|=(temp<<((rmdat32&7)<<1));
    1.76 +                        ST(rmdat32 & 7) = ST(0);
    1.77 +                        temp = (tag >> ((TOP & 7) << 1)) & 3;
    1.78 +                        tag &= ~(3 << (((TOP + rmdat32) & 7) << 1));
    1.79 +                        tag |= (temp << (((TOP + rmdat32) & 7) << 1));
    1.80                          x87_pop();
    1.81                          cycles-=3;
    1.82                          return;