[mupen64plus] 135/262: Support separated MIPS I and MIPS III FPR

Sven Eckelmann ecsv-guest at moszumanska.debian.org
Thu Nov 26 05:59:26 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 8a08feb5d759dac3bac294cf81cf5e8f28f90a62
Author: Sven Eckelmann <sven.eckelmann at gmx.de>
Date:   Sat Sep 26 22:55:01 2009 +0200

    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".
---
 debian/changelog                  |   2 +
 debian/patches/separate_fpr.patch | 310 ++++++++++++++++++++++++++++++++++++++
 debian/patches/series             |   1 +
 3 files changed, 313 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 904c5af..4aa7001 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -16,6 +16,8 @@ mupen64plus (1.5+dfsg1-5) UNRELEASED; urgency=low
     - Add interpreter_x86_fldcw.patch, Correctly set floating point control word
     - 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
   * debian/control:
     - Depend on liblzma-dev for lzma and xz support
 
diff --git a/debian/patches/separate_fpr.patch b/debian/patches/separate_fpr.patch
new file mode 100644
index 0000000..ebaaeb2
--- /dev/null
+++ b/debian/patches/separate_fpr.patch
@@ -0,0 +1,310 @@
+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 940b4c409ae9cd66eb804b29e83d3be0df3fb69a..c86ce96821ad6dad5eff1de75506ba246e38a311 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);
+@@ -194,6 +195,35 @@ void savestates_save()
+     free(filename);
+ }
+ 
++
++static void set_cop1_register(void)
++{
++    if (reg_cop0[12] & 0x04000000)
++    {
++        int i;
++        for (i=0; i<32; i++)
++        {
++            reg_cop1_double[i]=(double*)&reg_cop1_fgr_64[i];
++            reg_cop1_simple[i]=(float*)&reg_cop1_fgr_64[i];
++        }
++    }
++    else
++    {
++        int i;
++        for (i=0; i<32; i++)
++        {
++            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]+=i&1;
++#else
++            reg_cop1_simple[i]+=(~i)&1;
++#endif
++        }
++    }
++}
++
+ void savestates_load()
+ {
+     char *filename, *file, buffer[1024];
+@@ -286,8 +316,10 @@ void savestates_load()
+     gzread(f, &llbit, 4);
+     gzread(f, reg, 32*8);
+     gzread(f, reg_cop0, 32*4);
++    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 d4318cd..316f79b 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -28,3 +28,4 @@ jttl_fix_romclosed.patch
 rice_nodebug.patch
 interpreter_x86_fldcw.patch
 system-liblzma.patch
+separate_fpr.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