int mmu040_movem;
uaecptr mmu040_movem_ea;
+uae_u32 mmu040_move16[4];
static void mmu_dump_ttr(const TCHAR * label, uae_u32 ttr)
{
}
ssw |= fc & MMU_SSW_TM; /* TM = FC */
+ regs.wb3_status = write ? 0x80 | (ssw & 0x7f) : 0;
+ regs.wb2_status = 0;
+
switch (size) {
case sz_byte:
ssw |= MMU_SSW_SIZE_B;
ssw |= MMU_SSW_SIZE_L;
break;
case 16: // MOVE16
- ssw |= MMU_SSW_SIZE_L; // ??
+ ssw |= MMU_SSW_SIZE_L; // ?? maybe MMU_SSW_SIZE_CL?
ssw |= MMU_SSW_TT0;
- write_log (_T("040 MMU MOVE16 FAULT!\n"));
+ regs.mmu_effective_addr &= ~15;
+ if (write) {
+ // clear normal writeback if MOVE16 write
+ regs.wb3_status &= ~0x80;
+ // wb2 = cacheline size writeback
+ regs.wb2_status = 0x80 | MMU_SSW_SIZE_CL | (ssw & 0x1f);
+ regs.wb2_address = regs.mmu_effective_addr;
+ write_log (_T("040 MMU MOVE16 WRITE FAULT!\n"));
+ }
break;
}
- regs.wb3_status = write ? 0x80 | (ssw & 0x7f) : 0;
if (!write)
ssw |= MMU_SSW_RW;
ismoves = false;
}
+void mmu_get_move16(uaecptr addr, uae_u32 *v, bool data, int size)
+{
+ struct mmu_atc_line *cl;
+ addr &= ~15;
+ for (int i = 0; i < 4; i++) {
+ uaecptr addr2 = addr + i * 4;
+ // addr,super,data
+ if ((!regs.mmu_enabled) || (mmu_match_ttr(addr2,regs.s != 0,data,false)!=TTR_NO_MATCH))
+ v[i] = phys_get_long(addr2);
+ else if (likely(mmu_lookup(addr2, data, false, &cl)))
+ v[i] = phys_get_long(mmu_get_real_address(addr2, cl));
+ else
+ v[i] = mmu_get_long_slow(addr2, regs.s != 0, data, size, false, cl);
+ }
+}
+
+void mmu_put_move16(uaecptr addr, uae_u32 *val, bool data, int size)
+{
+ struct mmu_atc_line *cl;
+ addr &= ~15;
+ for (int i = 0; i < 4; i++) {
+ uaecptr addr2 = addr + i * 4;
+ // addr,super,data
+ if ((!regs.mmu_enabled) || (mmu_match_ttr_write(addr2,regs.s != 0,data,val[i],size,false)==TTR_OK_MATCH))
+ phys_put_long(addr2,val[i]);
+ else if (likely(mmu_lookup(addr2, data, true, &cl)))
+ phys_put_long(mmu_get_real_address(addr2, cl), val[i]);
+ else
+ mmu_put_long_slow(addr2, val[i], regs.s != 0, data, size, false, cl);
+ }
+}
+
+
void REGPARAM2 mmu_op_real(uae_u32 opcode, uae_u16 extra)
{
bool super = (regs.dfc & 4) != 0;
printf ("\tuae_u32 v[4];\n");
genamode (curi, curi->smode, "srcreg", curi->size, "mems", 0, 2, 0);
genamode (curi, curi->dmode, "dstreg", curi->size, "memd", 0, 2, 0);
- printf ("\tmemsa &= ~15;\n");
- printf ("\tmemda &= ~15;\n");
- if (using_mmu >= 68040) {
+ if (using_mmu == 68040) {
+ printf ("\tget_move16_mmu (memsa, mmu040_move16);\n");
+ printf ("\tput_move16_mmu (memda, mmu040_move16);\n");
+ } else if (using_mmu == 68060) {
printf ("\tget_move16_mmu (memsa, v);\n");
printf ("\tput_move16_mmu (memda, v);\n");
} else {
+ printf ("\tmemsa &= ~15;\n");
+ printf ("\tmemda &= ~15;\n");
printf ("\tv[0] = %s (memsa);\n", srcl);
printf ("\tv[1] = %s (memsa + 4);\n", srcl);
printf ("\tv[2] = %s (memsa + 8);\n", srcl);
extern int mmu040_movem;
extern uaecptr mmu040_movem_ea;
+extern uae_u32 mmu040_move16[4];
extern bool mmu_pagesize_8k;
extern uae_u16 mmu_opcode;
return cl->phys | (addr & mmu_pagemask);
}
-static ALWAYS_INLINE void mmu_get_move16(uaecptr addr, uae_u32 *v, bool data, int size)
-{
- struct mmu_atc_line *cl;
- for (int i = 0; i < 4; i++) {
- uaecptr addr2 = addr + i * 4;
- // addr,super,data
- if ((!regs.mmu_enabled) || (mmu_match_ttr(addr2,regs.s != 0,data,false)!=TTR_NO_MATCH))
- v[i] = phys_get_long(addr2);
- else if (likely(mmu_lookup(addr2, data, false, &cl)))
- v[i] = phys_get_long(mmu_get_real_address(addr2, cl));
- else
- v[i] = mmu_get_long_slow(addr2, regs.s != 0, data, size, false, cl);
- }
-}
+extern void mmu_get_move16(uaecptr addr, uae_u32 *v, bool data, int size);
+extern void mmu_put_move16(uaecptr addr, uae_u32 *val, bool data, int size);
static ALWAYS_INLINE uae_u32 mmu_get_long(uaecptr addr, bool data, int size, bool rmw)
{
mmu_put_long_slow(addr, val, regs.s != 0, data, size, rmw, cl);
}
-static ALWAYS_INLINE void mmu_put_move16(uaecptr addr, uae_u32 *val, bool data, int size)
-{
- struct mmu_atc_line *cl;
- for (int i = 0; i < 4; i++) {
- uaecptr addr2 = addr + i * 4;
- // addr,super,data
- if ((!regs.mmu_enabled) || (mmu_match_ttr_write(addr2,regs.s != 0,data,val[i],size,false)==TTR_OK_MATCH))
- phys_put_long(addr2,val[i]);
- else if (likely(mmu_lookup(addr2, data, true, &cl)))
- phys_put_long(mmu_get_real_address(addr2, cl), val[i]);
- else
- mmu_put_long_slow(addr2, val[i], regs.s != 0, data, size, false, cl);
- }
-}
-
static ALWAYS_INLINE void mmu_put_word(uaecptr addr, uae_u16 val, bool data, int size, bool rmw)
{
struct mmu_atc_line *cl;
#define MMU_SSW_SIZE_B 0x0020
#define MMU_SSW_SIZE_W 0x0040
#define MMU_SSW_SIZE_L 0x0000
+#define MMU_SSW_SIZE_CL 0x0060
#define MMU_SSW_RW 0x0100
#define MMU_SSW_LK 0x0200
#define MMU_SSW_ATC 0x0400
#ifdef FPUEMU
fpdata fp[8];
fpdata fp_result;
+ uae_u32 fp_result_status;
uae_u32 fpcr, fpsr, fpiar;
- uae_u32 fpsr_highbyte;
uae_u32 fpu_state;
uae_u32 fpu_exp_state;
fpdata exp_src1, exp_src2;
uae_u32 mmu_fslw;
uae_u32 mmu_fault_addr, mmu_effective_addr;
uae_u16 mmu_ssw;
+ uae_u32 wb2_address;
uae_u32 wb3_data;
- uae_u16 wb3_status;
+ uae_u8 wb3_status, wb2_status;
int mmu_enabled;
int mmu_page_size;
#endif
x_put_long (m68k_areg (regs, 7), oldpc);
break;
case 0x7: // access error stack frame (68040)
- for (i = 0 ; i < 7 ; i++) {
+
+ for (i = 3; i >= 0; i--) {
+ // WB1D/PD0,PD1,PD2,PD3
m68k_areg (regs, 7) -= 4;
- x_put_long (m68k_areg (regs, 7), 0);
- }
+ x_put_long (m68k_areg (regs, 7), mmu040_move16[i]);
+ }
+
m68k_areg (regs, 7) -= 4;
- x_put_long (m68k_areg (regs, 7), regs.wb3_data);
+ x_put_long (m68k_areg (regs, 7), 0); // WB1A
+ m68k_areg (regs, 7) -= 4;
+ x_put_long (m68k_areg (regs, 7), 0); // WB2D
m68k_areg (regs, 7) -= 4;
- x_put_long (m68k_areg (regs, 7), regs.mmu_fault_addr);
+ x_put_long (m68k_areg (regs, 7), regs.wb2_address); // WB2A
+ m68k_areg (regs, 7) -= 4;
+ x_put_long (m68k_areg (regs, 7), regs.wb3_data); // WB3D
m68k_areg (regs, 7) -= 4;
- x_put_long (m68k_areg (regs, 7), regs.mmu_fault_addr);
- m68k_areg (regs, 7) -= 2;
+ x_put_long (m68k_areg (regs, 7), regs.mmu_fault_addr); // WB3A
+
+ m68k_areg (regs, 7) -= 4;
+ x_put_long (m68k_areg (regs, 7), regs.mmu_fault_addr); // FA
+
+ m68k_areg (regs, 7) -= 2;
x_put_word (m68k_areg (regs, 7), 0);
m68k_areg (regs, 7) -= 2;
- x_put_word (m68k_areg (regs, 7), 0);
+ x_put_word (m68k_areg (regs, 7), regs.wb2_status);
+ regs.wb2_status = 0;
m68k_areg (regs, 7) -= 2;
x_put_word (m68k_areg (regs, 7), regs.wb3_status);
regs.wb3_status = 0;
- m68k_areg (regs, 7) -= 2;
+
+ m68k_areg (regs, 7) -= 2;
x_put_word (m68k_areg (regs, 7), ssw);
m68k_areg (regs, 7) -= 4;
x_put_long (m68k_areg (regs, 7), regs.mmu_effective_addr);