--- hatari/src/uae-cpu/fpp.c 2019/04/01 07:10:42 1.1.1.2 +++ hatari/src/uae-cpu/fpp.c 2019/04/01 07:15:37 1.1.1.8 @@ -10,7 +10,7 @@ * This file is distributed under the GNU Public License, version 2 or at * your option any later version. Read the file gpl.txt for details. */ -static char rcsid[] = "Hatari $Id: fpp.c,v 1.1.1.2 2019/04/01 07:10:42 root Exp $"; +const char FPP_rcsid[] = "Hatari $Id: fpp.c,v 1.1.1.8 2019/04/01 07:15:37 root Exp $"; #define __USE_ISOC9X /* We might be able to pick up a NaN */ @@ -20,7 +20,13 @@ static char rcsid[] = "Hatari $Id: fpp.c #include "hatari-glue.h" #include "memory.h" #include "newcpu.h" -#include "fpp-unknown.h" +#include "savestate.h" + +#if defined(powerpc) || defined(__mc68020__) +# include "fpp-ieee-be.h" +#else +# include "fpp-unknown.h" +#endif #if 1 @@ -197,8 +203,8 @@ STATIC_INLINE int get_fp_value (uae_u32 int mode; int reg; uae_u32 ad = 0; - static int sz1[8] = { 4, 4, 12, 12, 2, 8, 1, 0 }; - static int sz2[8] = { 4, 4, 12, 12, 2, 8, 2, 0 }; + static const int sz1[8] = { 4, 4, 12, 12, 2, 8, 1, 0 }; + static const int sz2[8] = { 4, 4, 12, 12, 2, 8, 2, 0 }; if ((extra & 0x4000) == 0) { *src = regs.fp[(extra >> 10) & 7]; @@ -325,8 +331,8 @@ STATIC_INLINE int put_fp_value (fptype v int mode; int reg; uae_u32 ad; - static int sz1[8] = { 4, 4, 12, 12, 2, 8, 1, 0 }; - static int sz2[8] = { 4, 4, 12, 12, 2, 8, 2, 0 }; + static const int sz1[8] = { 4, 4, 12, 12, 2, 8, 1, 0 }; + static const int sz2[8] = { 4, 4, 12, 12, 2, 8, 2, 0 }; if ((extra & 0x4000) == 0) { regs.fp[(extra >> 10) & 7] = value; @@ -616,7 +622,7 @@ void fdbcc_opp (uae_u32 opcode, uae_u16 void fscc_opp (uae_u32 opcode, uae_u16 extra) { - uae_u32 ad; + uae_u32 ad = 0; int cc; #if DEBUG_FPP @@ -652,7 +658,7 @@ void ftrapcc_opp (uae_u32 opcode, uaecpt op_illg (opcode); } if (cc) - Exception (7, oldpc - 2); + Exception (7, oldpc - 2, M68000_EXCEPTION_SRC_CPU); } void fbcc_opp (uae_u32 opcode, uaecptr pc, uae_u32 extra) @@ -676,7 +682,7 @@ void fbcc_opp (uae_u32 opcode, uaecptr p void fsave_opp (uae_u32 opcode) { - uae_u32 ad; + uae_u32 ad = 0; int incr = (opcode & 0x38) == 0x20 ? -1 : 1; int i; @@ -690,7 +696,7 @@ void fsave_opp (uae_u32 opcode) return; } - if (cpu_level == 4) { + if (currprefs.cpu_level == 4) { /* 4 byte 68040 IDLE frame. */ if (incr < 0) { ad -= 4; @@ -728,7 +734,7 @@ void fsave_opp (uae_u32 opcode) void frestore_opp (uae_u32 opcode) { - uae_u32 ad; + uae_u32 ad = 0; uae_u32 d; int incr = (opcode & 0x38) == 0x20 ? -1 : 1; @@ -741,7 +747,7 @@ void frestore_opp (uae_u32 opcode) op_illg (opcode); return; } - if (cpu_level == 4) { + if (currprefs.cpu_level == 4) { /* 68040 */ if (incr < 0) { /* @@@ This may be wrong. */ @@ -865,7 +871,7 @@ void fpp_opp (uae_u32 opcode, uae_u16 ex } } else if (extra & 0x2000) { /* FMOVEM FPP->memory */ - uae_u32 ad; + uae_u32 ad = 0; int incr = 0; if (get_fp_ad (opcode, &ad) == 0) { @@ -901,7 +907,7 @@ void fpp_opp (uae_u32 opcode, uae_u16 ex m68k_areg (regs, opcode & 7) = ad; } else { /* FMOVEM memory->FPP */ - uae_u32 ad; + uae_u32 ad = 0; if (get_fp_ad (opcode, &ad) == 0) { m68k_setpc (m68k_getpc () - 4); @@ -931,7 +937,8 @@ void fpp_opp (uae_u32 opcode, uae_u16 ex case 6: case 7: { - uae_u32 ad, list = 0; + uae_u32 ad = 0; + uae_u32 list = 0; int incr = 0; if (extra & 0x2000) { /* FMOVEM FPP->memory */ @@ -1344,3 +1351,56 @@ void fpp_opp (uae_u32 opcode, uae_u16 ex } #endif + + +void restore_fpu (void) +{ + int model, i; + + model = restore_u32(); + + for (i = 0; i < 8; i++) { + uae_u32 w1 = restore_u32 (); + uae_u32 w2 = restore_u32 (); + uae_u32 w3 = restore_u16 (); + regs.fp[i] = to_exten (w1, w2, w3); + } + + regs.fpcr = restore_u32 (); + regs.fpsr = restore_u32 (); + regs.fpiar = restore_u32 (); +} + + +void save_fpu (void) +{ + int model,i; + + switch (currprefs.cpu_level) { + case 3: + model = 68881; + break; + case 4: + model = 68040; + break; + case 6: + model = 68060; + break; + default: + model = 0; + } + + save_u32 (model); + + for (i = 0; i < 8; i++) { + uae_u32 w1, w2, w3; + from_exten (regs.fp[i], &w1, &w2, &w3); + save_u32 (w1); + save_u32 (w2); + save_u16 (w3); + } + + save_u32 (regs.fpcr); + save_u32 (regs.fpsr); + save_u32 (regs.fpiar); +}