Re: [hatari-devel] Basic cpu testsuite |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/hatari-devel Archives
]
> Good catch. It also lacks check if multiple control register bits are
> set at the same time (or none) which works strangely on 68060.. I'll
> attach patch later today.
Patch attached.
- FMOVE control register<>Dn/An missing validation added.
- FMOVEM fpp<>ea missing -(an)/(an)+ validation added. (Oddly enough
control register FMOVEM do not have same addressing mode restrictions)
diff --git "a/C:\\Users\\TONI~1.WIL\\AppData\\Local\\Temp\\TortoiseGit\\fpp-fc4d3c3.001.cpp" "b/C:\\projects\\winuae\\src\\fpp.cpp"
index 2150a5e4..7289de23 100644
--- "a/C:\\Users\\TONI~1.WIL\\AppData\\Local\\Temp\\TortoiseGit\\fpp-fc4d3c3.001.cpp"
+++ "b/C:\\projects\\winuae\\src\\fpp.cpp"
@@ -2825,41 +2825,52 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
case 4:
case 5:
+ // FMOVE Control Register <> Data or Address register
if ((opcode & 0x38) == 0) {
+ // Dn
if (fault_if_no_fpu (opcode, extra, 0, pc))
return;
+ // Only single selected control register is allowed
+ // All control register bits unset = FPIAR
+ uae_u16 bits = extra & (0x1000 | 0x0800 | 0x0400);
+ if (bits && bits != 0x1000 && bits != 0x0800 && bits != 0x400) {
+ // 68060 does not generate f-line if multiple bits are set
+ // but it also works unexpectedly, just do nothing for now.
+ if (currprefs.fpu_model != 68060)
+ fpu_noinst(opcode, pc);
+ return;
+ }
if (extra & 0x2000) {
if (extra & 0x1000)
m68k_dreg (regs, opcode & 7) = fpp_get_fpcr();
if (extra & 0x0800)
m68k_dreg (regs, opcode & 7) = fpp_get_fpsr();
- if (extra & 0x0400)
+ if ((extra & 0x0400) || !bits)
m68k_dreg (regs, opcode & 7) = regs.fpiar;
} else {
if (extra & 0x1000)
fpp_set_fpcr(m68k_dreg (regs, opcode & 7));
if (extra & 0x0800)
fpp_set_fpsr(m68k_dreg (regs, opcode & 7));
- if (extra & 0x0400)
+ if ((extra & 0x0400) || !bits)
regs.fpiar = m68k_dreg (regs, opcode & 7);
}
} else if ((opcode & 0x38) == 0x08) {
+ // An
if (fault_if_no_fpu (opcode, extra, 0, pc))
return;
+ // Only FPIAR can be moved to/from address register
+ // All bits unset = FPIAR
+ uae_u16 bits = extra & (0x1000 | 0x0800 | 0x0400);
+ // 68060, An and all bits unset: f-line
+ if ((bits && bits != 0x0400) || (!bits && currprefs.fpu_model == 68060)) {
+ fpu_noinst(opcode, pc);
+ return;
+ }
if (extra & 0x2000) {
- if (extra & 0x1000)
- m68k_areg (regs, opcode & 7) = fpp_get_fpcr();
- if (extra & 0x0800)
- m68k_areg (regs, opcode & 7) = fpp_get_fpsr();
- if (extra & 0x0400)
- m68k_areg (regs, opcode & 7) = regs.fpiar;
+ m68k_areg (regs, opcode & 7) = regs.fpiar;
} else {
- if (extra & 0x1000)
- fpp_set_fpcr(m68k_areg (regs, opcode & 7));
- if (extra & 0x0800)
- fpp_set_fpsr(m68k_areg (regs, opcode & 7));
- if (extra & 0x0400)
- regs.fpiar = m68k_areg (regs, opcode & 7);
+ regs.fpiar = m68k_areg (regs, opcode & 7);
}
} else if ((opcode & 0x3f) == 0x3c) {
if ((extra & 0x2000) == 0) {
@@ -2892,7 +2903,7 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
return;
}
} else if (extra & 0x2000) {
- /* FMOVEM FPP->memory */
+ /* FMOVEM Control Register->Memory */
uae_u32 ad;
int incr = 0;
@@ -2930,7 +2941,7 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
if ((opcode & 0x38) == 0x20)
m68k_areg (regs, opcode & 7) = ad;
} else {
- /* FMOVEM memory->FPP */
+ /* FMOVEM Memory->Control Register */
uae_u32 ad;
int incr = 0;
@@ -2972,6 +2983,7 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
case 6:
case 7:
{
+ // FMOVEM FPP<>Memory
uae_u32 ad, list = 0;
int incr = 1;
int regdir = 1;
@@ -2981,6 +2993,18 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
}
if (fault_if_no_fpu (opcode, extra, ad, pc))
return;
+
+ if ((extra & 0x2000) && (opcode & 0x38) == 0x18) {
+ // FMOVEM FPP->Memory: (An)+ not supported
+ fpu_noinst(opcode, pc);
+ return;
+ }
+ if (!(extra & 0x2000) && (opcode & 0x38) == 0x20) {
+ // FMOVEM Memory->FPP: -(An) not supported
+ fpu_noinst(opcode, pc);
+ return;
+ }
+
switch ((extra >> 11) & 3)
{
case 0: /* static pred */
@@ -3005,10 +3029,10 @@ static void fpuop_arithmetic2 (uae_u32 opcode, uae_u16 extra)
}
}
if (extra & 0x2000) {
- /* FMOVEM FPP->memory */
+ /* FMOVEM FPP->Memory */
ad = fmovem2mem (ad, list, incr, regdir);
} else {
- /* FMOVEM memory->FPP */
+ /* FMOVEM Memory->FPP */
ad = fmovem2fpp (ad, list, incr, regdir);
}
if ((opcode & 0x38) == 0x18 || (opcode & 0x38) == 0x20) // (an)+ or -(an)