--- nono/m680x0/m68030mmu.cpp 2026/04/29 17:04:31 1.1.1.2 +++ nono/m680x0/m68030mmu.cpp 2026/04/29 17:04:54 1.1.1.5 @@ -1,10 +1,9 @@ // // nono -// Copyright (C) 2017 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // -#include "header.h" -#include "mystring.h" #include "m68030core.h" #include "m68030bus.h" #include "m68030ea.h" @@ -29,8 +28,8 @@ // ディスクリプタ #define MMU_DESC_S (0x00000100) #define MMU_DESC_CI (0x00000040) -#define MMU_DESC_M (0x00000010) -#define MMU_DESC_U (0x00000008) +#define MMU_DESC_M (0x00000010) +#define MMU_DESC_U (0x00000008) #define MMU_DESC_WP (0x00000004) #define MMU_DESC_DT (0x00000003) @@ -89,11 +88,11 @@ IPRINTF(int indent, const char *fmt, ... // テーブルサーチ操作クラス -class m68030MMU +class m68030MMU final { public: m68030MMU(m68kcpu *); - virtual ~m68030MMU() { } + ~m68030MMU() { } // サーチを実行 void search(); @@ -273,10 +272,11 @@ m68kcpu::SetTT(int n, uint32 data) mmu_enable_changed(); } -// アクセスがこの TT と一致するか調べる。 +// アクセスがこの TT とマッチするか調べる。 // ssw_laddr は上位32ビットが cpu->bus.ssw、下位32ビットが論理アドレス // (下24ビットは呼び出し側でマスクしなくてよい)。 -// 一致すれば true を返す。 +// この TT が有効でアドレスがマッチすれば true を返す。 +// (TT:E は演算に織り込んである、このすぐ上の SetTT() のコメント参照) bool m68030TT::Match(uint64 ssw_laddr) { @@ -1554,7 +1554,7 @@ m68030MMU::dtname(uint32 dt) static char buf[32]; switch (dt) { case DT_INVALID: return "invalid"; - case DT_PAGE: return "page"; + case DT_PAGE: return "page"; case DT_VALID4: return "valid4"; case DT_VALID8: return "valid8"; } @@ -1737,15 +1737,17 @@ m68030_mmu_translate_peek(m68kcpu *cpu, // まず TT をチェック paddr = laddr; - for (int i = 0; i < 2; i++) { - m68030TT& tt = cpu->mmu_tt[i]; - uint64 ssw = (uint64)(SSW_BUS_R | fc) << 32; - if (tt.Match(ssw | laddr)) { - // 一致した。 - // CI はここでは使わないため、一致したことだけわかればよい - DPRINTF(0, "translate_peek: result $%08x (match tt)", - (uint32)paddr); - return paddr; + if (__predict_false(cpu->mmu_tt_quick[laddr >> 24] != 0)) { + uint64 ssw_laddr = ((uint64)(SSW_BUS_R | fc) << 32) | laddr; + for (int i = 0; i < 2; i++) { + m68030TT& tt = cpu->mmu_tt[i]; + if (tt.Match(ssw_laddr)) { + // 一致した。 + // CI はここでは使わないため、一致したことだけわかればよい + DPRINTF(0, "translate_peek: result $%08x (match tt)", + (uint32)paddr); + return paddr; + } } } @@ -1781,10 +1783,17 @@ m68030_mmu_translate_peek(m68kcpu *cpu, return paddr; } } + + // TC が有効だがヒットしなかったらバスエラー + DPRINTF(0, "translate_peek: result BusErr"); + return (uint64)-1; } - DPRINTF(0, "translate_peek: result BusErr"); - return (uint64)-1; + // TT が無効かまたは有効でもヒットせず、 + // かつ TC も無効だったら (こっちは「有効でヒットせず」は含まない)、 + // 論理アドレスをそのまま返す + DPRINTF(0, "translate_peek: result $%08x (no translation)", laddr); + return laddr; } // @@ -1854,7 +1863,7 @@ get_fc(m68kcpu *cpu) } // MMU 不当命令 (2ワード目で確定) -void +static void mmu_op_illg2(m68kcpu *cpu) { cpulog(1, "MMU 不当命令 %04x %04x", RegIR, RegIR2);