From: Toni Wilen Date: Thu, 4 Oct 2018 13:52:38 +0000 (+0300) Subject: Fix 68030 MMU PTEST, eamode 6 is valid, PTEST level 1 to 7 does not check TTRs. X-Git-Tag: 4100~68 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=77132c28915e0ff84470dba5bf3a61607e657997;p=francis%2Fwinuae.git Fix 68030 MMU PTEST, eamode 6 is valid, PTEST level 1 to 7 does not check TTRs. --- diff --git a/cpummu30.cpp b/cpummu30.cpp index 85e6eda3..fd2493a3 100644 --- a/cpummu30.cpp +++ b/cpummu30.cpp @@ -72,6 +72,10 @@ uae_u32 mmu030_fmovem_store[2]; uae_u8 mmu030_cache_state; struct mmu030_access mmu030_ad[MAX_MMU030_ACCESS]; +static void mmu030_ptest_atc_search(uaecptr logical_addr, uae_u32 fc, bool write); +static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level); +static TT_info mmu030_decode_tt(uae_u32 TT); + #if MMU_DPAGECACHE030 #define MMUFASTCACHE_ENTRIES030 256 struct mmufastcache030 @@ -285,6 +289,25 @@ void mmu030_flush_atc_all(void) { mmu030_flush_cache(0xffffffff); } +/* -- Helper function for MMU instructions -- */ +static uae_u32 mmu_op30_helper_get_fc(uae_u16 next) { + switch (next & 0x0018) { + case 0x0010: + return (next & 0x7); + case 0x0008: + return (m68k_dreg(regs, next & 0x7) & 0x7); + case 0x0000: + if (next & 1) { + return (regs.dfc); + } else { + return (regs.sfc); + } + default: + write_log(_T("MMU_OP30 ERROR: bad fc source! (%04X)\n"), next & 0x0018); + return 0; + } +} + /* -- MMU instructions -- */ static bool mmu_op30_invea(uae_u32 opcode) @@ -293,7 +316,7 @@ static bool mmu_op30_invea(uae_u32 opcode) int rreg = opcode & 7; // Dn, An, (An)+, -(An), immediate and PC-relative not allowed - if (eamode == 0 || eamode == 1 || eamode == 3 || eamode == 4 || eamode == 6 || (eamode == 7 && rreg > 1)) + if (eamode == 0 || eamode == 1 || eamode == 3 || eamode == 4 || (eamode == 7 && rreg > 1)) return true; return false; } @@ -453,7 +476,7 @@ bool mmu_op30_ptest (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra) if (!level) { mmu030_ptest_atc_search(extra, fc, write); } else { - ret = mmu030_ptest_table_search(extra, fc, write, level); + ret = mmu030_table_search(extra, fc, write, level); if (a) { m68k_areg (regs, areg) = ret; } @@ -541,24 +564,6 @@ bool mmu_op30_pflush (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra) return false; } -/* -- Helper function for MMU instructions -- */ -uae_u32 mmu_op30_helper_get_fc(uae_u16 next) { - switch (next&0x0018) { - case 0x0010: - return (next&0x7); - case 0x0008: - return (m68k_dreg(regs, next&0x7)&0x7); - case 0x0000: - if (next&1) { - return (regs.dfc); - } else { - return (regs.sfc); - } - default: - write_log(_T("MMU_OP30 ERROR: bad fc source! (%04X)\n"), next&0x0018); - return 0; - } -} /* Transparent Translation Registers (TT0 and TT1) * @@ -1182,7 +1187,7 @@ static void mmu030_atc_handle_history_bit(int entry_num) { /* This functions searches through the translation tables. It can be used * for PTEST (levels 1 to 7). Using level 0 creates an ATC entry. */ -uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level) { +static uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level) { /* During table walk up to 7 different descriptors are used: * root pointer, descriptors fetched from function code lookup table, * tables A, B, C and D and one indirect descriptor */ @@ -1616,7 +1621,7 @@ uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level) { } /* This function is used for PTEST level 0. */ -void mmu030_ptest_atc_search(uaecptr logical_addr, uae_u32 fc, bool write) { +static void mmu030_ptest_atc_search(uaecptr logical_addr, uae_u32 fc, bool write) { int i; mmu030.status = 0; @@ -1644,16 +1649,6 @@ void mmu030_ptest_atc_search(uaecptr logical_addr, uae_u32 fc, bool write) { mmu030.status |= mmu030.atc[i].physical.modified ? MMUSR_MODIFIED : 0; } -/* This function is used for PTEST level 1 - 7. */ -uae_u32 mmu030_ptest_table_search(uaecptr logical_addr, uae_u32 fc, bool write, int level) { - if (mmu030_match_ttr(logical_addr, fc, write)&TT_OK_MATCH) { - return 0; - } else { - return mmu030_table_search(logical_addr, fc, write, level); - } -} - - /* Address Translation Cache * * The ATC uses a pseudo-least-recently-used algorithm to keep track of diff --git a/include/cpummu030.h b/include/cpummu030.h index 631e58e2..e321c9d0 100644 --- a/include/cpummu030.h +++ b/include/cpummu030.h @@ -44,13 +44,6 @@ bool mmu_op30_pmove (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra); bool mmu_op30_ptest (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra); bool mmu_op30_pflush (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra); -uae_u32 mmu_op30_helper_get_fc(uae_u16 next); - -void mmu030_ptest_atc_search(uaecptr logical_addr, uae_u32 fc, bool write); -uae_u32 mmu030_ptest_table_search(uaecptr extra, uae_u32 fc, bool write, int level); -uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level); - - typedef struct { uae_u32 addr_base; uae_u32 addr_mask; @@ -58,7 +51,6 @@ typedef struct { uae_u32 fc_mask; } TT_info; -TT_info mmu030_decode_tt(uae_u32 TT); bool mmu030_decode_tc(uae_u32 TC, bool); bool mmu030_decode_rp(uae_u64 RP); diff --git a/newcpu.cpp b/newcpu.cpp index 0b2a998d..28ae2b5d 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -4064,7 +4064,7 @@ static bool mmu_op30_invea(uae_u32 opcode) int rreg = opcode & 7; // Dn, An, (An)+, -(An), immediate and PC-relative not allowed - if (eamode == 0 || eamode == 1 || eamode == 3 || eamode == 4 || eamode == 6 || (eamode == 7 && rreg > 1)) + if (eamode == 0 || eamode == 1 || eamode == 3 || eamode == 4 || (eamode == 7 && rreg > 1)) return true; return false; }