--- nono/m680x0/m68030mmu.cpp 2026/04/29 17:04:49 1.1.1.4 +++ nono/m680x0/m68030mmu.cpp 2026/04/29 17:04:54 1.1.1.5 @@ -272,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) { @@ -1736,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; + } } } @@ -1780,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; } //