[mupen64plus] 139/262: Correct mapping of floating point registers in MIPS I mode

Sven Eckelmann ecsv-guest at moszumanska.debian.org
Thu Nov 26 05:59:27 UTC 2015


This is an automated email from the git hooks/post-receive script.

ecsv-guest pushed a commit to branch master
in repository mupen64plus.

commit e8df6923500225631b1efaad5bb12421f7419d5c
Author: Sven Eckelmann <sven.eckelmann at gmx.de>
Date:   Wed Sep 30 13:29:04 2009 +0200

    Correct mapping of floating point registers in MIPS I mode
    
    MIPS r4300i supports different floating point register sets. As the
    instruction set reference state that these are separated but not
    distinct and a program maybe switch between both with 'mtc0 $x, status'
    we must be sure that they don't override each other on write access in
    a non-compliant way.
    This is implemented by doing operations in separate floating point
    register banks for 32 bit and 64 bit wide FGRs. After a switch both gets
    synced to match the behavior specified in the documentation. Inside the
    savestate only the 64 bit wide FGRs gets saved and before a save and
    after a load of a savestate a sync of both is forced.
    More informations about these registers can be found in
     * Charles Brice, "MIPS IV Instruction Set" Rev. 3.2, September 1995 in
       "B.3 Floating-Point Registers".
     * Joe Heinrich, "MIPS R4000 Microprocessor User’s Manual",
       Second Edition in "6.3 FPU Programming Model" and
       "B.4 Computational Instructions"
---
 debian/changelog                           |   4 +-
 debian/patches/correct_fpr32_mapping.patch | 225 ++++++++++++++++++++++
 debian/patches/separate_fpr.patch          | 289 -----------------------------
 debian/patches/series                      |   2 +-
 4 files changed, 228 insertions(+), 292 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index a9a141f..492e0a2 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -3,8 +3,8 @@ mupen64plus (1.5+dfsg1-6) UNRELEASED; urgency=low
   * debian/patches:
     - Add system-liblzma.patch, use liblzma from debian instead of buildin
       (Closes: #543552)
-    - Add separate_fpr.patch, Correct emulation of separated FPR for MIPS I and
-      MIPS III
+    - Add correct_fpr32_mapping.patch, Correct emulation of shared 32 bit wide
+      and 64 bit wide FPR in MIPS I and MIPS III mode
   * debian/control:
     - Depend on liblzma-dev for lzma and xz support
 
diff --git a/debian/patches/correct_fpr32_mapping.patch b/debian/patches/correct_fpr32_mapping.patch
new file mode 100644
index 0000000..4ac2b73
--- /dev/null
+++ b/debian/patches/correct_fpr32_mapping.patch
@@ -0,0 +1,225 @@
+Description: Correct mapping of floating point registers in MIPS I mode
+ MIPS r4300i supports different floating point register sets. As the instruction
+ set reference state that these are separated but not distinct and a program
+ maybe switch between both with 'mtc0 $x, status' we must be sure that they
+ don't override each other on write access in a non-compliant way.
+ This is implemented by doing operations in separate floating point register
+ banks for 32 bit and 64 bit wide FGRs. After a switch both gets synced to
+ match the behavior specified in the documentation. Inside the savestate only
+ the 64 bit wide FGRs gets saved and before a save and after a load of a
+ savestate a sync of both is forced.
+ More informations about these registers can be found in
+ * Charles Brice, "MIPS IV Instruction Set" Rev. 3.2, September 1995 in
+   "B.3 Floating-Point Registers".
+ * Joe Heinrich, "MIPS R4000 Microprocessor User’s Manual", Second Edition in
+   "6.3 FPU Programming Model" and "B.4 Computational Instructions"
+Bug: http://code.google.com/p/mupen64plus/issues/detail?id=51
+Author: Sven Eckelmann <sven.eckelmann at gmx.de>
+
+---
+diff --git a/main/savestates.c b/main/savestates.c
+index f2df55824d0696d04472a268b6f9aae1aec731c4..8902f325166a2efe6ba0444a6745b9cd59909b3a 100644
+--- a/main/savestates.c
++++ b/main/savestates.c
+@@ -104,6 +104,65 @@ char* savestates_get_filename()
+     return filename;
+ }
+ 
++static void set_cop1_register(void)
++{
++    if (reg_cop0[12] & 0x04000000)
++    {
++        int i;
++        unsigned int *tmp;
++        for (i=0; i<32; i++)
++        {
++            /* Savestate has 64 bit wide FGR - so just map it correctly */
++            reg_cop1_double[i]=(double*)&reg_cop1_fgr_64[i];
++            reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i];
++#ifdef _BIG_ENDIAN
++            /* least significant 32-bits of double must share place with float */
++            reg_cop1_simple[i] += 1;
++#endif
++        }
++    }
++    else
++    {
++        int i;
++        unsigned int *tmp;
++        for (i=0; i<32; i++)
++        {
++            reg_cop1_double[i]=(double*)&reg_cop1_fgr_32[i&(~1)];
++	    /* Savestate has 64 bit wide FGR - copy data from it to 32 bit FGR */
++            tmp=(unsigned int*)&reg_cop1_fgr_64[i];
++            reg_cop1_simple[i]=(float*)&reg_cop1_fgr_32[i&(~1)];
++            /* least significant 32-bits of double must share place with lower numbered float */
++#ifndef _BIG_ENDIAN
++            reg_cop1_simple[i]+=i&1;
++#else
++            reg_cop1_simple[i]+=(~i)&1;
++#endif
++            *(unsigned int*)(reg_cop1_simple[i]) = *tmp;
++        }
++    }
++}
++
++static void unify_fgr()
++{
++    if ((reg_cop0[12] & 0x04000000) == 0)
++    {
++        int i;
++        unsigned int *tmp;
++        for (i=0; i<32; i++)
++        {
++            /* Savestate has 64 bit wide FGR
++	       we have to save data from 32 bit wide FGR back to 64 bit FGR before saving */
++            tmp=(unsigned int*)&reg_cop1_fgr_64[i];
++#ifdef _BIG_ENDIAN
++            /* least significant 32-bits of double must share place with float */
++            tmp[i] += 1;
++#endif
++	    *tmp=*((unsigned int*)&reg_cop1_simple[i]);
++        }
++    }
++    /* else is unimportant because 64 bit wide FGR can always be saved without conversation */
++}
++
+ void savestates_save()
+ {
+     char *filename, *file, buffer[1024];
+@@ -173,6 +232,7 @@ void savestates_save()
+     gzwrite(f, reg_cop0, 32*4);
+     gzwrite(f, &lo, 8);
+     gzwrite(f, &hi, 8);
++    unify_fgr();
+     gzwrite(f, reg_cop1_fgr_64, 32*8);
+     gzwrite(f, &FCR0, 4);
+     gzwrite(f, &FCR31, 4);
+@@ -317,6 +377,7 @@ void savestates_load()
+     gzread(f, &lo, 8);
+     gzread(f, &hi, 8);
+     gzread(f, reg_cop1_fgr_64, 32*8);
++    set_cop1_register();
+     gzread(f, &FCR0, 4);
+     gzread(f, &FCR31, 4);
+     gzread(f, tlb_e, 32*sizeof(tlb));
+diff --git a/r4300/compare_core.c b/r4300/compare_core.c
+index 248ba5eaea597be2354ed6af024e6aec76b2e482..638cfbdaaa3cabfd8060eed3d4a06870ba11447a 100644
+--- a/r4300/compare_core.c
++++ b/r4300/compare_core.c
+@@ -145,6 +145,12 @@ void compare_core()
+       if (iFirst) { printf(errHead); iFirst = 0; }
+       display_error("cop0");
+       }
++    fread (comp_reg, 32, sizeof(int), f);
++    if (memcmp(reg_cop1_fgr_32, comp_reg, 32*sizeof(int)))
++    {
++      if (iFirst) { printf(errHead); iFirst = 0; }
++      display_error("cop1");
++    }
+     fread (comp_reg, 32, sizeof(long long int), f);
+     if (memcmp(reg_cop1_fgr_64, comp_reg, 32*sizeof(long long int)))
+     {
+@@ -171,6 +177,7 @@ void compare_core()
+     fwrite(&PC->addr, 4, sizeof(int), f);
+     fwrite(reg, 32, sizeof(long long int), f);
+     fwrite(reg_cop0, 32, sizeof(int), f);
++    fwrite(reg_cop1_fgr_32, 32, sizeof(int), f);
+     fwrite(reg_cop1_fgr_64, 32, sizeof(long long int), f);
+     /*fwrite(&rdram[0x31280/4], 1, sizeof(int), f);
+     fwrite(&FCR31, 4, 1, f);*/
+diff --git a/r4300/cop0.c b/r4300/cop0.c
+index 1ee72aa2c8e9805aeb1699cc1d4ca7f6e3126829..6d5f5720dee8a4d0d0c19e6d547bf124d172f96c 100644
+--- a/r4300/cop0.c
++++ b/r4300/cop0.c
+@@ -94,24 +94,35 @@ void MTC0(void)
+          if (rrt & 0x04000000)
+            {
+           int i;
++          unsigned int *tmp;
+           for (i=0; i<32; i++)
+             {
+                reg_cop1_double[i]=(double*)&reg_cop1_fgr_64[i];
++	       tmp=(unsigned int*)reg_cop1_simple[i];
+                reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i];
++#ifdef _BIG_ENDIAN
++            /* least significant 32-bits of double must share place with float */
++            reg_cop1_simple[i] += 1;
++#endif
++	       *(unsigned int*)(reg_cop1_simple[i]) = *tmp;
+             }
+            }
+          else
+            {
+           int i;
++          unsigned int *tmp;
+           for (i=0; i<32; i++)
+             {
+-               if(!(i&1))
+-             reg_cop1_double[i]=(double*)&reg_cop1_fgr_64[i>>1];
++               reg_cop1_double[i]=(double*)&reg_cop1_fgr_32[i&(~1)];
++               tmp=(unsigned int*)reg_cop1_simple[i];
++               reg_cop1_simple[i]=(float*)&reg_cop1_fgr_32[i&(~1)];
++               /* least significant 32-bits of double must share place with lower numbered float */
+ #ifndef _BIG_ENDIAN
+-               reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i>>1]+(i&1);
++               reg_cop1_simple[i]+=i&1;
+ #else
+-               reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i>>1]+(1-(i&1));
++               reg_cop1_simple[i]+=(~i)&1;
+ #endif
++	       *(unsigned int*)(reg_cop1_simple[i]) = *tmp;
+             }
+            }
+       }
+diff --git a/r4300/pure_interp.c b/r4300/pure_interp.c
+index 734e244c95b34a4e167b7975f3e7aaf3765dabda..1315088d461fcabd9b56d21713c91bac4180c22a 100644
+--- a/r4300/pure_interp.c
++++ b/r4300/pure_interp.c
+@@ -1044,31 +1044,35 @@ static void MTC0()
+          if (rrt & 0x04000000)
+            {
+           int i;
++          unsigned int *tmp;
+           for (i=0; i<32; i++)
+             {
+-               //reg_cop1_fgr_64[i]=reg_cop1_fgr_32[i];
+                reg_cop1_double[i]=(double*)&reg_cop1_fgr_64[i];
++	       tmp=(unsigned int*)reg_cop1_simple[i];
+                reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i];
++#ifdef _BIG_ENDIAN
++            /* least significant 32-bits of double must share place with float */
++            reg_cop1_simple[i] += 1;
++#endif
++	       *(unsigned int*)(reg_cop1_simple[i]) = *tmp;
+             }
+            }
+          else
+            {
+           int i;
++          unsigned int *tmp;
+           for (i=0; i<32; i++)
+             {
+-               //reg_cop1_fgr_32[i]=reg_cop1_fgr_64[i]&0xFFFFFFFF;
+-               //if (i<16) reg_cop1_double[i*2]=(double*)&reg_cop1_fgr_32[i*2];
+-               //reg_cop1_double[i]=(double*)&reg_cop1_fgr_64[i & 0xFFFE];
+-               if(!(i&1))
+-             reg_cop1_double[i]=(double*)&reg_cop1_fgr_64[i>>1];
+-               //reg_cop1_double[i]=(double*)&reg_cop1_fgr_64[i];
+-               //reg_cop1_simple[i]=(float*)&reg_cop1_fgr_32[i];
+-               //reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i & 0xFFFE]+(i&1);
++               reg_cop1_double[i]=(double*)&reg_cop1_fgr_32[i&(~1)];
++               tmp=(unsigned int*)reg_cop1_simple[i];
++               reg_cop1_simple[i]=(float*)&reg_cop1_fgr_32[i&(~1)];
++               /* least significant 32-bits of double must share place with lower numbered float */
+ #ifndef _BIG_ENDIAN
+-               reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i>>1]+(i&1);
++               reg_cop1_simple[i]+=i&1;
+ #else
+-               reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i>>1]+(1-(i&1));
++               reg_cop1_simple[i]+=(~i)&1;
+ #endif
++	       *(unsigned int*)(reg_cop1_simple[i]) = *tmp;
+             }
+            }
+       }
diff --git a/debian/patches/separate_fpr.patch b/debian/patches/separate_fpr.patch
deleted file mode 100644
index 64d2129..0000000
--- a/debian/patches/separate_fpr.patch
+++ /dev/null
@@ -1,289 +0,0 @@
-Description: Support separated MIPS I and MIPS III FPR
- MIPS r4300i supports different floating point register sets. As the instruction
- set reference state that these are separated and a program maybe switch between
- both with 'mtc0 $x, status' we must be sure that they don't override each other
- on write access.
- The savestate format must be changed so that the MIPS I FPRs can be saved in
- parallel to the MIPS III floating point registers. More informations about
- these registers can be found in "MIPS IV Instruction Set" Revision 3.2 by
- Charles Brice from September 1995 in "B.3 Floating-Point Registers".
-Bug: http://code.google.com/p/mupen64plus/issues/detail?id=51
-Author: Sven Eckelmann <sven.eckelmann at gmx.de>
-
----
-diff --git a/main/savestates.c b/main/savestates.c
-index f2df55824d0696d04472a268b6f9aae1aec731c4..0f52650f1a09ec3348d4caba89336b0578f91285 100644
---- a/main/savestates.c
-+++ b/main/savestates.c
-@@ -37,7 +37,7 @@
- #include "../opengl/osd.h"
- 
- const char* savestate_magic = "M64+SAVE";
--const int savestate_version = 0x00010000;  /* 1.0 */
-+const int savestate_version = 0x00010001;  /* 1.1 */
- 
- extern unsigned int interp_addr;
- 
-@@ -173,6 +173,7 @@ void savestates_save()
-     gzwrite(f, reg_cop0, 32*4);
-     gzwrite(f, &lo, 8);
-     gzwrite(f, &hi, 8);
-+    gzwrite(f, reg_cop1_fgr_32, 32*4);
-     gzwrite(f, reg_cop1_fgr_64, 32*8);
-     gzwrite(f, &FCR0, 4);
-     gzwrite(f, &FCR31, 4);
-@@ -210,12 +211,13 @@ static void set_cop1_register(void)
-         int i;
-         for (i=0; i<32; i++)
-         {
--               if(!(i&1))
--             reg_cop1_double[i]=(double*)&reg_cop1_fgr_64[i>>1];
-+            reg_cop1_double[i]=(double*)&reg_cop1_fgr_32[i&(~1)];
-+            reg_cop1_simple[i]=(float*)&reg_cop1_fgr_32[i&(~1)];
-+            /* least significant 32-bits of double must share place with lower numbered float */
- #ifndef _BIG_ENDIAN
--               reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i>>1]+(i&1);
-+            reg_cop1_simple[i]+=i&1;
- #else
--               reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i>>1]+(1-(i&1));
-+            reg_cop1_simple[i]+=(~i)&1;
- #endif
-         }
-     }
-@@ -316,6 +318,7 @@ void savestates_load()
-     set_cop1_register();
-     gzread(f, &lo, 8);
-     gzread(f, &hi, 8);
-+    gzread(f, reg_cop1_fgr_32, 32*4);
-     gzread(f, reg_cop1_fgr_64, 32*8);
-     gzread(f, &FCR0, 4);
-     gzread(f, &FCR31, 4);
-diff --git a/r4300/compare_core.c b/r4300/compare_core.c
-index 248ba5eaea597be2354ed6af024e6aec76b2e482..638cfbdaaa3cabfd8060eed3d4a06870ba11447a 100644
---- a/r4300/compare_core.c
-+++ b/r4300/compare_core.c
-@@ -145,6 +145,12 @@ void compare_core()
-       if (iFirst) { printf(errHead); iFirst = 0; }
-       display_error("cop0");
-       }
-+    fread (comp_reg, 32, sizeof(int), f);
-+    if (memcmp(reg_cop1_fgr_32, comp_reg, 32*sizeof(int)))
-+    {
-+      if (iFirst) { printf(errHead); iFirst = 0; }
-+      display_error("cop1");
-+    }
-     fread (comp_reg, 32, sizeof(long long int), f);
-     if (memcmp(reg_cop1_fgr_64, comp_reg, 32*sizeof(long long int)))
-     {
-@@ -171,6 +177,7 @@ void compare_core()
-     fwrite(&PC->addr, 4, sizeof(int), f);
-     fwrite(reg, 32, sizeof(long long int), f);
-     fwrite(reg_cop0, 32, sizeof(int), f);
-+    fwrite(reg_cop1_fgr_32, 32, sizeof(int), f);
-     fwrite(reg_cop1_fgr_64, 32, sizeof(long long int), f);
-     /*fwrite(&rdram[0x31280/4], 1, sizeof(int), f);
-     fwrite(&FCR31, 4, 1, f);*/
-diff --git a/r4300/cop0.c b/r4300/cop0.c
-index 1ee72aa2c8e9805aeb1699cc1d4ca7f6e3126829..98ab76b514c720ccc10a62064426f0131705f3ee 100644
---- a/r4300/cop0.c
-+++ b/r4300/cop0.c
-@@ -105,12 +105,13 @@ void MTC0(void)
-           int i;
-           for (i=0; i<32; i++)
-             {
--               if(!(i&1))
--             reg_cop1_double[i]=(double*)&reg_cop1_fgr_64[i>>1];
-+               reg_cop1_double[i]=(double*)&reg_cop1_fgr_32[i&(~1)];
-+               reg_cop1_simple[i]=(float*)&reg_cop1_fgr_32[i&(~1)];
-+               /* least significant 32-bits of double must share place with lower numbered float */
- #ifndef _BIG_ENDIAN
--               reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i>>1]+(i&1);
-+               reg_cop1_simple[i]+=i&1;
- #else
--               reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i>>1]+(1-(i&1));
-+               reg_cop1_simple[i]+=(~i)&1;
- #endif
-             }
-            }
-diff --git a/r4300/pure_interp.c b/r4300/pure_interp.c
-index 734e244c95b34a4e167b7975f3e7aaf3765dabda..9a614d4909ae5cb82d4884a85bc60b113e7a1945 100644
---- a/r4300/pure_interp.c
-+++ b/r4300/pure_interp.c
-@@ -1046,7 +1046,6 @@ static void MTC0()
-           int i;
-           for (i=0; i<32; i++)
-             {
--               //reg_cop1_fgr_64[i]=reg_cop1_fgr_32[i];
-                reg_cop1_double[i]=(double*)&reg_cop1_fgr_64[i];
-                reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i];
-             }
-@@ -1056,18 +1055,13 @@ static void MTC0()
-           int i;
-           for (i=0; i<32; i++)
-             {
--               //reg_cop1_fgr_32[i]=reg_cop1_fgr_64[i]&0xFFFFFFFF;
--               //if (i<16) reg_cop1_double[i*2]=(double*)&reg_cop1_fgr_32[i*2];
--               //reg_cop1_double[i]=(double*)&reg_cop1_fgr_64[i & 0xFFFE];
--               if(!(i&1))
--             reg_cop1_double[i]=(double*)&reg_cop1_fgr_64[i>>1];
--               //reg_cop1_double[i]=(double*)&reg_cop1_fgr_64[i];
--               //reg_cop1_simple[i]=(float*)&reg_cop1_fgr_32[i];
--               //reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i & 0xFFFE]+(i&1);
-+               reg_cop1_double[i]=(double*)&reg_cop1_fgr_32[i&(~1)];
-+               reg_cop1_simple[i]=(float*)&reg_cop1_fgr_32[i&(~1)];
-+               /* least significant 32-bits of double must share place with lower numbered float */
- #ifndef _BIG_ENDIAN
--               reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i>>1]+(i&1);
-+               reg_cop1_simple[i]+=i&1;
- #else
--               reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i>>1]+(1-(i&1));
-+               reg_cop1_simple[i]+=(~i)&1;
- #endif
-             }
-            }
-diff --git a/tools/savestate_convert.c b/tools/savestate_convert.c
-index f639d31a682d6e605f1c23f2fe821df101dfc488..d2738a64906112ad8ed9d4f3ba2d50fb4124c86f 100644
---- a/tools/savestate_convert.c
-+++ b/tools/savestate_convert.c
-@@ -26,7 +26,8 @@
- 
- /* savestate file header: magic number and version number */
- const char *savestate_magic = "M64+SAVE";
--const int savestate_newest_version = 0x00010000;  // 1.0
-+const int savestate_combinedfpr_version = 0x00010000;  // 1.0
-+const int savestate_newest_version = 0x00010001;  // 1.1
- 
- /* Data field lengths */
- 
-@@ -78,6 +79,7 @@ char reg[32][8];
- char reg_cop0[32][4];
- char lo[8];
- char hi[8];
-+char reg_cop1_fgr_32[32][4];
- char reg_cop1_fgr_64[32][8];
- char FCR0[4];
- char FCR31[4];
-@@ -100,6 +102,7 @@ int allocate_memory(void);
- void free_memory(void);
- 
- int load_original_mupen64(const char *filename);
-+int load_combinedfpr(const char *filename);
- int save_newest(const char *filename);
- 
- /* Main Function - parse arguments, check version, load state file, overwrite state file with new one */
-@@ -153,6 +156,10 @@ int main(int argc, char *argv[])
-         printf("Warning: old savestate file format.  This is presumed to be from the original Mupen64 or Mupen64Plus version 1.4 or earlier.\n");
-         load_function = load_original_mupen64;
-     }
-+    else if (iVersion == savestate_combinedfpr_version) {
-+        printf("Warning: old savestate file format without separated floating registers.\n");
-+        load_function = load_combinedfpr;
-+    }
-     else if (iVersion == savestate_newest_version)
-     {
-         printf("This savestate file is already up to date (version %08x)\n", savestate_newest_version);
-@@ -303,6 +310,96 @@ int load_original_mupen64(const char *filename)
-     gzread(f, next_vi, 4);
-     gzread(f, vi_field, 4);
- 
-+    memcpy(reg_cop1_fgr_32, reg_cop1_fgr_64, 32 * 4);
-+
-+    queuelength = 0;
-+    while(queuelength < SIZE_MAX_EVENTQUEUE)
-+    {
-+        if (gzread(f, eventqueue + queuelength, 4) != 4)
-+        {
-+            printf("Error: savestate file '%s' is corrupt.\n", filename);
-+            return 2;
-+        }
-+        if (*((unsigned int*) &eventqueue[queuelength]) == 0xFFFFFFFF)
-+        {
-+            queuelength += 4;
-+            break;
-+        }
-+        gzread(f, eventqueue + queuelength + 4, 4);
-+        queuelength += 8;
-+    }
-+
-+    if (queuelength >= SIZE_MAX_EVENTQUEUE)
-+    {
-+        printf("Error: savestate file '%s' has event queue larger than %i bytes.\n", filename, SIZE_MAX_EVENTQUEUE);
-+        return 3;
-+    }
-+
-+    gzclose(f);
-+    return 0;
-+}
-+
-+int load_combinedfpr(const char *filename)
-+{
-+    char buffer[8];
-+    int i;
-+    gzFile f;
-+
-+    f = gzopen(filename, "rb");
-+
-+    if (f == NULL)
-+    {
-+        printf("Error: savestate file '%s' is corrupt.\n", filename);
-+        return 1;
-+    }
-+
-+    /* Ignore magic */
-+    gzread(f, buffer,8);
-+
-+    /* Ignore version */
-+    gzread(f, buffer,4);
-+
-+    gzread(f, rom_md5, 32);
-+
-+    gzread(f, rdram_register, SIZE_REG_RDRAM);
-+    gzread(f, mips_register, SIZE_REG_MIPS);
-+    gzread(f, pi_register, SIZE_REG_PI);
-+    gzread(f, sp_register, SIZE_REG_SP);
-+    gzread(f, rsp_register, SIZE_REG_RSP);
-+    gzread(f, si_register, SIZE_REG_SI);
-+    gzread(f, vi_register, SIZE_REG_VI);
-+    gzread(f, ri_register, SIZE_REG_RI);
-+    gzread(f, ai_register, SIZE_REG_AI);
-+    gzread(f, dpc_register, SIZE_REG_DPC);
-+    gzread(f, dps_register, SIZE_REG_DPS);
-+
-+    gzread(f, rdram, 0x800000);
-+    gzread(f, SP_DMEM, 0x1000);
-+    gzread(f, SP_IMEM, 0x1000);
-+    gzread(f, PIF_RAM, 0x40);
-+
-+    gzread(f, flashram, SIZE_FLASHRAM_INFO);
-+
-+    gzread(f, tlb_LUT_r, 0x100000*4);
-+    gzread(f, tlb_LUT_w, 0x100000*4);
-+
-+    gzread(f, llbit, 4);
-+    gzread(f, reg, 32*8);
-+    gzread(f, reg_cop0, 32*4);
-+    gzread(f, lo, 8);
-+    gzread(f, hi, 8);
-+    gzread(f, reg_cop1_fgr_64[0], 32 * 8);
-+    gzread(f, FCR0, 4);
-+    gzread(f, FCR31, 4);
-+    gzread(f, tlb_e[0], 32 * SIZE_TLB_ENTRY);
-+    gzread(f, PCaddr, 4);
-+
-+    gzread(f, next_interupt, 4);
-+    gzread(f, next_vi, 4);
-+    gzread(f, vi_field, 4);
-+
-+    memcpy(reg_cop1_fgr_32, reg_cop1_fgr_64, 32 * 4);
-+
-     queuelength = 0;
-     while(queuelength < SIZE_MAX_EVENTQUEUE)
-     {
-@@ -378,6 +475,7 @@ int save_newest(const char *filename)
-     gzwrite(f, reg_cop0[0], 32*4);
-     gzwrite(f, lo, 8);
-     gzwrite(f, hi, 8);
-+    gzwrite(f, reg_cop1_fgr_32[0], 32*4);
-     gzwrite(f, reg_cop1_fgr_64[0], 32*8);
-     gzwrite(f, FCR0, 4);
-     gzwrite(f, FCR31, 4);
diff --git a/debian/patches/series b/debian/patches/series
index 8bed6c2..cc82755 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -29,4 +29,4 @@ rice_nodebug.patch
 interpreter_x86_fldcw.patch
 load-fpr-location.patch
 system-liblzma.patch
-separate_fpr.patch
+correct_fpr32_mapping.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/mupen64plus.git



More information about the Pkg-games-commits mailing list