File:  [Isaki's NoNo m68k/m88k emulator] / nono / m680x0 / m68040mmu.h
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:05:57 2026 UTC (3 months ago) by root
Branches: MAIN, Isaki
CVS tags: v027, HEAD
nono 1.7.0

//
// nono
// Copyright (C) 2024 nono project
// Licensed under nono-license.txt
//

#pragma once

struct m68040MMU
{
	//    3                   2                   1                   0
	//  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
	// +-------------------------------------+-+-+-+---+-+---+-+-+-+---+
	// |       Physical Address (4K/8K)      : | |G|U10|S|CM |M|U|W|PDT|
	// +-------------------------------------+-+-+-+---+-+---+-+-+-+---+
	//                                        ^ ^
	//                                        | |
	//                                        +-+-- UR (ユーザ用予約)
	static const uint32 DESC_G			= 0x00000400;
	static const uint32 DESC_S			= 0x00000080;
	static const uint32 DESC_CM			= 0x00000060;
	static const uint32 DESC_M			= 0x00000010;
	static const uint32 DESC_U			= 0x00000008;
	static const uint32 DESC_W			= 0x00000004;
	static const uint32 DESC_DT			= 0x00000003;

	// ATCEntry.desc は PDT/UDT どちらから作られても bit0 を Resident とする。
	static const uint32 DESC_R 			= 0x00000001;

	// PDT は
	// %00 無効
	// %01 常駐
	// %10 間接
	// %11 常駐
	static const uint32 PDT_INVALID		= 0;
	static const uint32 PDT_INDIRECT	= 2;

	// UDT は
	// %00 無効
	// %01 無効
	// %10 常駐
	// %11 常駐
};

class m68040RP
{
	// SRP, URP
	//
	//    3                   2                   1                   0
	//  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
	// +---------------------------------------------+-----------------+
	// |                 Root Pointer                |       0         |
	// +---------------------------------------------+-----------------+

 public:
	static const uint32 ADDR_MASK	= 0xfffffe00;
};

class m68040TT
{
	//    3                   2                   1                   0
	//  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
	// +---------------+---------------+-+-+-+-+-+-+---+-+-+-+-+-+-+-+-+
	// |LogicalAddrBase|LogicalAddrMask|E| S |     | U | |CM |   |W|   |
	// +---------------+---------------+-+-+-+-+-+-+---+-+-+-+-+-+-+-+-+

 public:
	static const uint32 MASK		= 0xffffe364;
	static const uint32 LBASE_MASK	= 0xff000000;
	static const uint32 LMASK_MASK	= 0x00ff0000;
	static const uint32 E			= 0x00008000;
	static const uint32 S_IGN		= 0x00004000;
	static const uint32 S_FC2		= 0x00002000;
	static const uint32 U_MASK		= 0x00000300;
	static const uint32 U1			= 0x00000200;
	static const uint32 U0			= 0x00000100;
	static const uint32 CM			= 0x00000060;
	static const uint32 W			= 0x00000004;

	m68040TT(const char *, uint32 *);
	~m68040TT();

	bool Match(busaddr addr) const;
	const char *GetName() const	{ return name; }

	uint32 base {};
	uint32 mask {};
	bool e {};
	bool s_ign {};
	bool s_fc2 {};
	uint32 u {};
	uint8 cm {};
	bool w {};

	uint32 *reg {};			// レジスタイメージ置き場 (&reg.*tt)
 private:
	const char *name {};	// 表示用のレジスタ名
};

class m68040TC
{
	//            1                   0
	//  5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
	// +-+-+---------------------------+
	// |E|P|         reserved          |
	// +-+-+---------------------------+

 public:
	static const uint16 MASK		= 0xc000;
	static const uint16 E			= 0x8000;	// 有効
	static const uint16 P			= 0x4000;	// ページサイズ(%1=8K)

	bool e {};
	bool ps4k {};				// ページサイズが 4K なら true (ビット定義と逆)
	uint32 table_mask {};		// ページテーブルアドレスのマスク
	uint32 tic_shift {};		// 論理アドレス TIC 部の右シフト量
	uint32 tic_mask {};			// 論理アドレス TIC 部のマスク
	uint32 page_mask {};		// ページディスクリプタの物理アドレスマスク
};

class m68040MMUSR
{
	//    3                   2                   1                   0
	//  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
	// +---------------------------------------+-+-+---+-+-+-+-+-+-+-+-+
	// |           Physical Address            |B|G| U |S|CM |M| |W|T|R|
	// +---------------------------------------+-+-+---+-+-+-+-+-+-+-+-+

 public:
	static const uint32 ADDR_MASK	= 0xfffff000;	// 物理アドレス
	static const uint32 B			= 0x00000800;	// バスエラー
	static const uint32 G           = 0x00000400;	// グローバル
	static const uint32 U_MASK		= 0x00000300;	// ユーザ領域
	static const uint32 U1			= 0x00000200;
	static const uint32 U0			= 0x00000100;
	static const uint32 S			= 0x00000080;	// スーパーバイザ保護
	static const uint32 CM			= 0x00000060;	// キャッシュモード
	static const uint32 M			= 0x00000010;	// 修正済み
	static const uint32 W			= 0x00000004;	// 書き込み保護
	static const uint32 T			= 0x00000002;	// 透過変換がヒット
	static const uint32 R			= 0x00000001;	// 常駐
};

// ATC エントリ
class m68040ATCEntry
{
 public:
	// タグは無効なら最下位ビットを立てる。これでマッチしなくなる。
	//
	//    3                   2                   1                    0
	//  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1  0
	// +-----+-+---------------------------------------+-------------+--+
	// |  0  |S|       Logical Address (4K/8K)       : |      0      |~V|
	// +-----+-+---------------------------------------+-------------+--+
	static const uint32 SUPER		= 0x10000000;
	static const uint32 INVALID		= 0x00000001;
	uint32 tag {};

	bool IsValid() const			{ return (tag & INVALID) == 0; }
	bool IsSuper() const			{ return (tag & SUPER) != 0; }
	void Invalidate()				{ tag |= INVALID; }

	// desc はページディスクリプタをそのまま持っておく。
	// ページディスクリプタなので PDT(下位2bit) は %01 か %11 なら Resident。
	//
	//    3                   2                   1                   0
	//  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
	// +-----------------------------------------+-+---+-+---+-+-+-+-+-+
	// |                 (not used)              |G|U10|S|CM |M|U|W|-|R|
	// +-----------------------------------------+-+---+-+---+-+-+-+-+-+
	uint32 paddr {};
	uint32 desc {};

	bool IsGlobal() const			{ return (desc & m68040MMU::DESC_G); }
	bool IsSuperProtected() const	{ return (desc & m68040MMU::DESC_S); }
	bool IsWriteProtected() const	{ return (desc & m68040MMU::DESC_W); }
	bool IsResident() const			{ return (desc & m68040MMU::DESC_R); }

	bool MatchStatus(busaddr laddr) const;
};

// ATC セット
class m68040ATCSet
{
 public:
	std::array<m68040ATCEntry, 4> entry {};
	uint LRU {};

	int GetEntry() const;
};

// ATC
class m68040ATC
{
 public:
	std::array<m68040ATCSet, 16> sets {};

	// アドレス (busaddr >> 4) からタグを作る際のマスク。
	// PS が 4K か 8K かで長さが違うため。
	uint32 tag_mask {};

	void Flush(bool s, bool global);
	void Flush(busaddr addr, bool global);
};

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.